2012-04-01 11 views
0

Ich baue eine benutzerdefinierte HTTP-Request-Klasse mit Sockets. Mein Code basiert auf der MSDN-Guid für asynchrone Sockets, aber leider funktioniert es nicht. Die Anfrage funktioniert gut, aber ich erhalte keine vollständige Antwort. Kann mir vielleicht jemand bei diesem Problem helfen? ist hier mein Code:Asynchroner Socket funktioniert nicht

private void BeginConnect() 
{ 
    //Connect To Server 
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
    socket.BeginConnect(this.ResolveUrl(_requestUri), new AsyncCallback(this.ConnectCallback), socket); 
} 
private void ConnectCallback(IAsyncResult ar) 
{ 
    //Get Socket 
    Socket socket = (Socket)ar.AsyncState; 

    //Complete Connection 
    socket.EndConnect(ar); 

    //Send HTTP Request 
    byte[] requestBytes = this.CreateRequest(); 
    socket.BeginSend(requestBytes, 0, requestBytes.Length, SocketFlags.None, new AsyncCallback(this.SendCallback), socket); 
} 
private void SendCallback(IAsyncResult ar) 
{ 
    //Get Socket 
    Socket socket = (Socket)ar.AsyncState; 

    //Complete Sending 
    socket.EndSend(ar); 

    // Create the state object. 
    StateObject state = new StateObject(); 
    state.WorkSocket = socket; 

    //Recieve Response 
    socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), state); 
} 
private void ReceiveCallback(IAsyncResult ar) 
{ 
    //Get StateObject 
    StateObject state = (StateObject)ar.AsyncState; 
    Socket socket = state.WorkSocket; 

    //Complete Receiving 
    int bytesRead = socket.EndReceive(ar); 
    if (bytesRead > 0) 
    { 
     //Save Already Received Data 
     state.ResponseBuilder.Append(Encoding.ASCII.GetString(state.Buffer, 0, bytesRead)); 

     //Get Rest Of The Data. 
     socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(this.ReceiveCallback), state); 
    } 
    else 
    { 
     if (state.ResponseBuilder.Length > 1) 
     { 
      //Shutdown Socket 
      socket.BeginDisconnect(false, new AsyncCallback(this.DisconnectCallback), state); 

      //Invoke Callback 
      SocketResponse resp = new SocketResponse(state.ResponseBuilder.ToString(), HttpStatusCode.Accepted); //TODO 
      _callback.Invoke(resp); 
     } 
    } 
} 
private void DisconnectCallback(IAsyncResult ar) 
{ 
    //Get Socket 
    StateObject state = (StateObject)ar.AsyncState; 
    Socket socket = state.WorkSocket; 

    //Shutdown Socket 
    socket.Shutdown(SocketShutdown.Both); 
    socket.Close(); 
} 
+0

Ich denke, es ist das übliche TCP-Problem. h. TCP ist ein Strom und kein protokollbasiertes Protokoll und somit kann ein Sendeanruf in mehrere Empfangsanrufe aufgeteilt werden. Einige mögliche Duplikate [1] (http://stackoverflow.com/q/5528234/445517) [2] (http://stackoverflow.com/q/8575659/445517) [3] (http: // stackoverflow. com/q/9895132/445517) – CodesInChaos

Antwort

0

TCP-Verbindungen sind Strom basiert. Die Menge der Daten, die Sie jedes Mal lesen können, beinhaltet ein Element der Zufälligkeit und Sie müssen die gelesenen Daten durchlaufen, bis Sie die gesamte Nachricht haben.

Das Implementieren von Sockets ist eine fehleranfällige Übung, wenn Sie keine vorherige Netzwerkerfahrung haben. Allerdings wurden alle diese Probleme in der Open-Source-Netzwerkkommunikationsbibliothek networkComms.net gelöst. Wenn Sie der sehr einfachen 11-Zeile, Beispiel here, bis zum Ende der Aufrufstruktur folgen, sehen Sie, wie asynchrone Sockets korrekt implementiert werden.

+0

Zwei wesentliche Nachteile IMO 1) Ich kann eine Protokollspezifikation nicht finden 2) GPL – CodesInChaos

Verwandte Themen