2013-07-31 114 views
2

我一直在使用TcpListener類在C#中編寫我自己的http Web服務器。現在,在任何人提到這個之前,我知道HttpListener,但之前使用過,由於防火牆異常和需要管理員帳戶等等,Ive有一些問題。對於我的應用程序,它更容易做出簡單的,建立網絡服務器。我一直在使用python應用程序連接到我的C#web服務器,併發送一個簡單的GET請求,並接收一個簡單的響應。C#迷你Http服務器,知道何時關閉連接

我的問題是這個..服務器應該關閉連接還是客戶端?我問,因爲如果我在發送響應後關閉服務器中的連接,我的Python應用程序並不總是讀取所有的響應。相反,套接字錯誤將被拋出「錯誤10054,'由對等重置連接'」。但是,如果我強制python應用程序關閉連接,我不知道如何檢測到我的C#服務器上,因爲C#TcpClient不包含斷開連接事件。那麼我該怎麼做?我如何知道連接的客戶端何時收到完整響應,以便我可以關閉連接?

目前,這個工作(用線程休眠)

// Write headers and body to the Socket 
     NetworkStream Stream = Client.GetStream(); 

     // Write Headers 
     byte[] Buffer = Encoding.UTF8.GetBytes(Headers); 
     Stream.Write(Buffer, 0, Buffer.Length); 

     // Write Response Data if Request method is not HEAD 
     if (Request.RequestMethod != HttpRequestMethod.HEAD) 
      Stream.Write(BodyByteArr, 0, BodyByteArr.Length); 

     Stream.Flush(); 

     System.Threading.Thread.Sleep(100); 
     Stream.Close(); 
     Client.Close(); 

我認爲我需要一個更好的選擇,然後Thread.sleep()方法,這可能無法正常工作或如果客戶需要更多的則睡眠時間來接收響應(慢速連接)

集管發送到HTTP服務器:

GET /test HTTP/1.1 
Host: 127.0.0.1 
Connection: close 

發送回客戶端接頭:

HTTP/1.1 200 OK 
Date: {Now} 
Server: MiniHttp-ASPServer 
Content-Type: text/plain; charset=utf-8 
Content-Length: {length} 
Connection: close 

{contents} 
+0

您發送給客戶端的標題是什麼? –

+0

在主帖子中添加 – Wilson212

+0

我猜想這是一個內容長度問題。我相信內容的長度只是身體的長度。您可以稍微調試一下這種方法,就是使用像Chrome這樣的健壯客戶端來查看它是否使用F12工具來處理不正確形成的請求(或者它是否完成處理請求)。 –

回答

0

你已經採取了看看同步和異步插座樣品在H [TTP://msdn.microsoft.com/en-us/library/w89fhyex.aspx] [1]

[1 ]:http://msdn.microsoft.com/en-us/library/w89fhyex.aspx

我認爲你可以在解決方案中使用一些邏輯。在同步服務器實例(片斷):

 while (true) { 
      Console.WriteLine("Waiting for a connection..."); 
      // Program is suspended while waiting for an incoming      connection. 
      Socket handler = listener.Accept(); 
      data = null; 

      // An incoming connection needs to be processed. 
      while (true) { 
       bytes = new byte[1024]; 
       int bytesRec = handler.Receive(bytes); 
       data += Encoding.ASCII.GetString(bytes,0,bytesRec); 
       if (data.IndexOf("<EOF>") > -1) { 
        break; 
       } 
      } 

      // Show the data on the console. 
      Console.WriteLine("Text received : {0}", data); 

      // Echo the data back to the client. 
      byte[] msg = Encoding.ASCII.GetBytes(data); 

      handler.Send(msg); 
      handler.Shutdown(SocketShutdown.Both); 
      handler.Close(); 
     } 

在客戶端:

  sender.Connect(remoteEP); 

      Console.WriteLine("Socket connected to {0}", 
           sender.RemoteEndPoint.ToString()); 

      // Encode the data string into a byte array. 
      byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>"); 

      // Send the data through the socket. 
      int bytesSent = sender.Send(msg); 

      // Receive the response from the remote device. 
      int bytesRec = sender.Receive(bytes); 
      Console.WriteLine("Echoed test = {0}", 
           Encoding.ASCII.GetString(bytes,0,bytesRec)); 

      // Release the socket. 
      sender.Shutdown(SocketShutdown.Both); 
      sender.Close(); 
+0

嗯,這並沒有真正回答我的問題,或者幫助我很多。我在我的腳本中加入了Socket.Shutdown()(我完全不知道這個方法),這似乎只有一點點幫助,但我仍然收到48個異步請求中的2個套接字錯誤。越來越近,但不完全:) – Wilson212

+0

好的。那麼你可能想看看Socket.ReceiveTimeout屬性找到:[鏈接] http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.receivetimeout.aspx此外,我仍然會鼓勵你在我給你的上一個鏈接中運行示例,看看它是否會給出一些見解。 – Dylan

0

從HTTP1.1摘自RFC:

如果在客戶端或服務器發送關閉令牌,該請求將成爲連接的最後一個。

所以,當你的服務器關閉連接它以前有一個連接回答:密切頭。

我不知道C#和它的TCP客戶端,但是在套接字上發送可能會失敗的原因有幾個。在您關閉應用程序之前,我看不到您處理這些問題。

您必須重試才能發送答案,直到確定完全讀取。 我認爲你的連接:關閉標題永遠不會到達你的客戶端,這就是「連接重置對等」的答案。