ERLEDIGT
NEIN
NEIN
ANTWORTEN
0
0
ZUGRIFFE
553
553
EMPFEHLEN
-
Hi,
ich arbeite an einem Client-Server-Projekt. Da ich mit asynchronen Sockets in .NET noch nicht so firm bin, nutze ich als Kommunikationsbibliothek eine leicht angepasste Version der MSDN-Beispiel-Implementierungen
http://msdn.microsoft.com/de-de/library/fx6588te.aspx
http://msdn.microsoft.com/de-de/library/bew39x2a.aspx
Mir ist bewusst, dass dies eine möglichst minimalistische Implementierung zu sein scheint, aber kann mir bitte jemand sagen, an welchen Stelle die Nutzung dieses Codes problematisch werden könnte? Und warum?
Mein Bibliothek funktioniert 90% der Zeit problemlos, selbst bei "größeren" Dateimengen (~15 KB)
Allerdings habe ich im Moment das Problem, dass wenn ich eine bestimmte Aktion ausführe zwar die richtigen Daten gesendet werden. Diese aber nicht komplett ankommen. Es fehlt in diesem Fall scheinbar das 1. kB.
Hier mein kompletter Quelltext für die Bibliothek:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282
Public Class StateObject Public ID As Integer = 0 ' Client socket. Public workSocket As Socket = Nothing ' Size of receive buffer. Public Const BufferSize As Integer = 1024 ' Receive buffer. Public buffer(BufferSize) As Byte ' Received data string. Public sb As New StringBuilder End Class 'StateObject Public Class AsyncronousServer Implements IDisposable Public allDone As New ManualResetEvent(False) 'informiert über ACCEPT Public MessageBuffer As Queue(Of Message) 'Public clients As New Hashtable '(Client-ID, StateObject) Public state As New StateObject Public localSock As Socket Public MsgEvent As ManualResetEvent ' wenn eine Nachricht erhalten wurde Public Sub New(ByVal listenEP As IPEndPoint, ByRef MBuffer As Queue(Of Message), ByRef newMsg As ManualResetEvent) localSock = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) localSock.Bind(listenEP) MessageBuffer = MBuffer MsgEvent = newMsg localSock.Listen(1) End Sub Public Sub Accept() localSock.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), localSock) End Sub Public Sub AcceptCallback(ByVal ar As IAsyncResult) ' Get the socket that handles the client request. Dim listener As Socket = CType(ar.AsyncState, Socket) ' End the operation. Dim handler As Socket = listener.EndAccept(ar) ' Create the state object for the async receive. state.workSocket = handler handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state) allDone.Set() End Sub 'AcceptCallback Public Sub read() state.workSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state) End Sub Public Sub ReadCallback(ByVal ar As IAsyncResult) Dim content As String = String.Empty ' Retrieve the state object and the handler socket ' from the asynchronous state object. Dim state As StateObject = CType(ar.AsyncState, StateObject) Dim handler As Socket = state.workSocket ' Read data from the client socket. Dim bytesRead As Integer = 0 Try ' Read data from the remote device. bytesRead = handler.EndReceive(ar) Catch ex As Exception Console.WriteLine("Verbindung zum Server verloren") End Try Try If bytesRead > 0 Then ' There might be more data, so store the data received so far. state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead)) content = state.sb.ToString() If bytesRead < StateObject.BufferSize Then ' All the data has been read from the ' client. Display it on the console. Dim msg As New Message(state.sb.ToString()) MessageBuffer.Enqueue(msg) MsgEvent.Set() state.sb.Remove(0, state.sb.Length) 'speicher leeren Else ' Not all data received. Get more. handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReadCallback), state) End If End If Catch ex As Exception Console.WriteLine("Fehler beim Lesen: " & ex.ToString()) Finally End Try End Sub 'ReadCallback Public Sub Send(ByVal ID As Integer, ByVal data As String) ' Convert the string data to byte data using UTF8 encoding. Dim byteData As Byte() = Encoding.UTF8.GetBytes(data) ' Begin sending the data to the remote device. state.workSocket.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), state) End Sub 'Send Private Sub SendCallback(ByVal ar As IAsyncResult) ' Retrieve the socket from the state object. Dim handler As Socket = CType(ar.AsyncState.workSocket, Socket) ' Complete sending the data to the remote device. Dim bytesSent As Integer = handler.EndSend(ar) read() ' wieder alles auf Lesen setzen End Sub 'SendCallback Public Sub closeAll() state.workSocket.Shutdown(SocketShutdown.Both) state.workSocket.Close() End Sub #Region "IDisposable Support" Private disposedValue As Boolean ' So ermitteln Sie überflüssige Aufrufe ' IDisposable Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then state.workSocket.Shutdown(SocketShutdown.Both) state.workSocket.Close() End If ' TODO: Nicht verwaltete Ressourcen (nicht verwaltete Objekte) freigeben und Finalize() unten überschreiben. ' TODO: Große Felder auf NULL festlegen. End If Me.disposedValue = True End Sub ' Dieser Code wird von Visual Basic hinzugefügt, um das Dispose-Muster richtig zu implementieren. Public Sub Dispose() Implements IDisposable.Dispose ' Ändern Sie diesen Code nicht. Fügen Sie oben in Dispose(ByVal disposing As Boolean) Bereinigungscode ein. Dispose(True) GC.SuppressFinalize(Me) End Sub #End Region End Class Public Class AsyncronousClient Implements IDisposable Public socktoserver As Socket ' ManualResetEvent instances signal completion. Private Shared connectDone As New ManualResetEvent(False) Private Shared sendDone As New ManualResetEvent(False) Private Shared receiveDone As New ManualResetEvent(False) Private newMsg As ManualResetEvent Private content As New StringBuilder() Private MessageBuffer As Queue(Of Message) Public Sub New(ByVal sock As Socket, ByRef MBuffer As Queue(Of Message), ByRef MsgEvent As ManualResetEvent) socktoserver = sock MessageBuffer = MBuffer newMsg = MsgEvent End Sub Public Function connect(ByVal remoteEP As EndPoint) As Boolean socktoserver.BeginConnect(remoteEP, New AsyncCallback(AddressOf ConnectCallback), socktoserver) connectDone.WaitOne() Return socktoserver.Connected End Function Private Sub ConnectCallback(ByVal ar As IAsyncResult) ' Retrieve the socket from the state object. Dim client As Socket = CType(ar.AsyncState, Socket) ' Complete the connection. client.EndConnect(ar) 'Console.WriteLine("Socket connected to {0}", client.RemoteEndPoint.ToString()) ' Signal that the connection has been made. connectDone.Set() End Sub 'ConnectCallback Public Sub Receive() ' Create the state object. Dim state As New StateObject state.workSocket = socktoserver ' Begin receiving the data from the remote device. socktoserver.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state) End Sub 'Receive Private Sub ReceiveCallback(ByVal ar As IAsyncResult) ' Retrieve the state object and the client socket ' from the asynchronous state object. Dim state As StateObject = CType(ar.AsyncState, StateObject) Dim client As Socket = state.workSocket Dim bytesRead As Integer = 0 Try ' Read data from the remote device. bytesRead = client.EndReceive(ar) Catch ex As Exception Console.WriteLine("Verbindung zum Server verloren") End Try If bytesRead > 0 Then ' There might be more data, so store the data received so far. state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, bytesRead)) content.Append(state.sb.ToString()) state.sb.Remove(0, state.sb.Length) 'speicher leeren If bytesRead < StateObject.BufferSize Then ' All the data has been read from the ' client. Display it on the console. Dim msg As New Message(content.ToString()) MessageBuffer.Enqueue(msg) 'state.sb.Remove(0, state.sb.Length) 'speicher leeren content.Remove(0, content.Length) newMsg.Set() Receive() Else ' Not all data received. Get more. client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, New AsyncCallback(AddressOf ReceiveCallback), state) End If 'newMsg.Reset() End If End Sub 'ReceiveCallback Public Sub Send(ByVal data As String) ' Convert the string data to byte data using UTF8 encoding. Dim byteData As Byte() = Encoding.UTF8.GetBytes(data) ' Begin sending the data to the remote device. socktoserver.BeginSend(byteData, 0, byteData.Length, 0, New AsyncCallback(AddressOf SendCallback), socktoserver) End Sub 'Send Private Sub SendCallback(ByVal ar As IAsyncResult) ' Retrieve the socket from the state object. Dim client As Socket = CType(ar.AsyncState, Socket) ' Complete sending the data to the remote device. Dim bytesSent As Integer = client.EndSend(ar) ' Signal that all bytes have been sent. sendDone.Set() Receive() ' wieder auf Lesen setzen End Sub 'SendCallback Public Sub close() socktoserver.Shutdown(SocketShutdown.Both) socktoserver.Close() End Sub #Region "IDisposable Support" Private disposedValue As Boolean ' So ermitteln Sie überflüssige Aufrufe ' IDisposable Protected Overridable Sub Dispose(ByVal disposing As Boolean) If Not Me.disposedValue Then If disposing Then close() End If ' TODO: Nicht verwaltete Ressourcen (nicht verwaltete Objekte) freigeben und Finalize() unten überschreiben. ' TODO: Große Felder auf NULL festlegen. End If Me.disposedValue = True End Sub ' Dieser Code wird von Visual Basic hinzugefügt, um das Dispose-Muster richtig zu implementieren. Public Sub Dispose() Implements IDisposable.Dispose ' Ändern Sie diesen Code nicht. Fügen Sie oben in Dispose(ByVal disposing As Boolean) Bereinigungscode ein. Dispose(True) GC.SuppressFinalize(Me) End Sub #End Region End Class
Ich habe mir auch schon mehrere Tutorials online angesehen. Diese behandeln meist aber nur die Grundlagen, wie im MSDN-Beispiel.
Danke schonmal für die Hilfe.
mfg LuigiEd<?php
getRich() or die "trying"
?>
Ähnliche Themen
-
Asynchroner SFTP-Upload
Von Afritus im Forum .NET CaféAntworten: 9Letzter Beitrag: 03.12.11, 10:10 -
Asynchroner Webservice mit Java
Von 00d4vid im Forum JavaAntworten: 0Letzter Beitrag: 05.03.10, 14:52 -
Wie mit dll packets in Client senden?
Von 113puma im Forum C/C++Antworten: 2Letzter Beitrag: 17.09.09, 00:14 -
[c; raw sockets] Problem beim Erstellen eines Packets
Von milchbubbi im Forum C/C++Antworten: 3Letzter Beitrag: 03.05.05, 22:16 -
IExplorer Platform // Script packets
Von iLu_is_a_loser im Forum C/C++Antworten: 4Letzter Beitrag: 21.04.05, 20:29





Zitieren
Login





