Async TCP Server für mehrere Clients
Ich habe einen TCP Server, lauscht asynchron auf eingehende verbindungen. Funktioniert auch alles Prima wenn nur ein client verbunden ist. Aber wenn es zwei oder mehr verbindungen, die der Server nicht die erste Nachricht. Wenn ich die debug-ReceiveCallback-Funktion, die ich sehen kann, ruft der Server die Länge der Nachricht, aber nicht die Daten. I. e. wenn ich den Anschluss von zwei Kunden und versuchen zum senden der ersten Nachricht: "Hallo", ruft der server: empfangen = 5; buffer= /0/0/0/0/0, also es wird nichts angezeigt. In der zweiten Nachricht des gleichen Kunden, wird der server bekommt die Daten.
so ist mein server sieht wie folgt aus:
private void StartServer()
{
try
{
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
serverSocket.Bind(new IPEndPoint(IPAddress.Any, 3333));
serverSocket.Listen(100);
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void AcceptCallback(IAsyncResult ar)
{
try
{
Socket clientSocket = serverSocket.EndAccept(ar);
clientSocketList.Add(clientSocket);
AppendToTextBox("ClientConnected");
clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), clientSocket);
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void ReceiveCallback(IAsyncResult ar)
{
try
{
int received = 0;
Socket current = (Socket)ar.AsyncState;
received = current.EndReceive(ar);
byte[] data = new byte[received];
if (received == 0)
{
return;
}
Array.Copy(buffer, data, received);
string text = Encoding.ASCII.GetString(data);
AppendToTextBox(text);
buffer = null;
Array.Resize(ref buffer, current.ReceiveBufferSize);
current.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), current);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
InformationsquelleAutor xvzwx | 2013-04-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Siehe das Beispiel bei http://msdn.microsoft.com/en-us/library/dxkwh6zw.aspx
Sie möchten, ändern Sie Ihren code so, dass er reserviert einen neuen Puffer jedes mal, wenn Sie anrufen
BeginReceive
:Müssen Sie einen Puffer pro client. Ansonsten, ein client kann überschreiben des Puffers von der anderen Clients.
clientSocket
für diestate
parameter derBeginReceive
, zu sehen, wie IhreReceiveCallback
ist wahrscheinlich gehen zu müssen,buffer
um die Daten interpretieren zu erhalten. Der link, den @Jim enthalten veranschaulicht eine Lösung für dieses problem, indem eine Instanz einer Klasse alsstate
parameter.InformationsquelleAutor Jim Mischel