C#迷你Http服务器,知道何时关闭连接
本文关键字:何时关 连接 迷你 Http 服务器 | 更新日期: 2023-09-27 18:25:49
我一直在使用TcpListener类用C#编写自己的http web服务器。现在,在有人提到这一点之前,我知道HttpListener,但在之前使用过它之后,由于防火墙异常和需要管理帐户等原因,我遇到了一些问题。对于我的应用程序,制作一个简单的、构建的web服务器更容易。我一直在使用python应用程序连接到我的C#Web服务器,发送一个简单的GET请求,并接收一个简单响应。
我的问题是。。服务器应该关闭连接,还是客户端应该关闭连接?我之所以这么问,是因为如果我在发送响应后关闭服务器中的连接,我的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}
您看过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();
摘自HTTP1.1 RFC:
如果客户端或服务器在Connection标头中发送关闭令牌,则该请求将成为连接的最后一个请求。
因此,当您的服务器关闭连接时,它以前必须使用connection:close标头进行应答。
我不知道C#,它是TCP客户端,但套接字上的发送可能会失败有几个原因。我看不出你在关闭应用程序之前处理过这些问题。
您必须重试发送答案,直到您确定答案已被完全读取。我认为你的Connection:close头永远不会到达你的客户端,这就是为什么答案是"对等重置连接"。