2016-05-15 16 views
0

Ich versuche, einfache Client-Server-App, basierend auf asynchronen Sockets zu schreiben. Alles funktioniert gut, bis ich versuche, mehrere Clients zu verbinden. Sie verbinden gut, aber nur die „neueste“ können die Daten an den Server senden, andere Ausnahme werfen:Async Sockets in C#

„IAsyncResult Objekt nicht zurückgegeben wurde“

Hier ist mein AcceptCallback Code:

private void AcceptCallback(IAsyncResult AR) 
{ 
    try 
    { 
     _clientSocket = _serverSocket.EndAccept(AR); 
     _buffer = new byte[_clientSocket.ReceiveBufferSize]; 
     _clientSocket.BeginReceive(_buffer, 0, _buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), null); 
     _serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null); 
     Console.WriteLine("Client connected!"); 
    } 
    catch (Exception ex) 
    { 
     Console.WriteLine(ex.Message); 
    } 
} 

Irgendwelche Ideen, was ist los? Ich lerne gerade, es könnte etwas dummes und offensichtliches sein, aber ich sehe es nicht.

Antwort

1

Durch Zuweisung _clientSocket = _serverSocket.EndAccept(AR); verlieren Sie die vorherige _clientSocket;

Ich würde Ihren Code wie folgt ändern (Hauptpunkt ist die Übergabe der notwendigen Informationen wie Socket, Puffer usw. in ObjectState Parameter).

Siehe Object Parameter BeginXXX Methoden .....

var tcpListener = new TcpListener(IPAddress.Any, 8088); 
tcpListener.Start(); 
tcpListener.BeginAcceptSocket(AsyncAccept, tcpListener); 

.......

void AsyncAccept(IAsyncResult ar) 
{ 
    var tcpListener = (TcpListener)ar.AsyncState; 
    var socket = tcpListener.EndAcceptSocket(ar); 
    if (ar.IsCompleted) 
    { 
     Console.WriteLine(socket.RemoteEndPoint + " connected..."); 
     var buf = new byte[0x10000]; 
     socket.BeginReceive(buf, 0, buf.Length, SocketFlags.None, AsyncRead, new Tuple<Socket, byte[]>(socket, buf)); 

     tcpListener.BeginAcceptSocket(AsyncAccept, tcpListener); 
    } 
} 

void AsyncRead(IAsyncResult ar) 
{ 
    var tuple = (Tuple<Socket, byte[]>)ar.AsyncState; 
    var socket = tuple.Item1; 
    var buf = tuple.Item2; 

    if (ar.IsCompleted) 
    { 
     var len = socket.EndReceive(ar); 
     var str = Encoding.UTF8.GetString(buf, 0, len); 
     Console.WriteLine(socket.RemoteEndPoint + ":" + str); 

     socket.BeginReceive(buf, 0, buf.Length, SocketFlags.None, AsyncRead, new Tuple<Socket, byte[]>(socket, buf)); 
    } 
}