Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/265.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基本HttpServer |如何正确地从NetworkStream读取数据_C# - Fatal编程技术网

C# 基本HttpServer |如何正确地从NetworkStream读取数据

C# 基本HttpServer |如何正确地从NetworkStream读取数据,c#,C#,我正在尝试制作一个基本的Web服务器用于实践,但是我认为我没有正确地从NetworkStream中阅读。。。在下面的图片中,您可以看到请求2和请求3没有两个分隔它们的换行符\r\n\r\n,这意味着我读取的数据更少 此外,请求挂起也没有明显的原因。我认为我使用networkStream.Close()正确地关闭了流和客户端和tcpClient.Close() 使用系统; Net系统; 使用System.Net.Sockets; 使用系统文本; 命名空间HttpServer { 班级计划 { 静

我正在尝试制作一个基本的Web服务器用于实践,但是我认为我没有正确地从NetworkStream中阅读。。。在下面的图片中,您可以看到请求2和请求3没有两个分隔它们的换行符
\r\n\r\n
,这意味着我读取的数据更少

此外,请求挂起也没有明显的原因。我认为我使用
networkStream.Close()正确地关闭了流和客户端
tcpClient.Close()

使用系统;
Net系统;
使用System.Net.Sockets;
使用系统文本;
命名空间HttpServer
{
班级计划
{
静态void Main(字符串[]参数)
{
var webserver=新程序();
webserver.Listen(12345);
}
公共静态无效进程TCPClientAsync(TcpClient TcpClient)
{
//获取用于读写的流对象
NetworkStream NetworkStream=tcpClient.GetStream();
字节[]缓冲区=readByteBufferFromNetworkStream(networkStream);
字符串请求=Encoding.UTF8.GetString(缓冲区);
控制台写入线(请求);
常量字符串HTTPNewLine=“\r\n”;
string html=“Hello from TestServer”;
string response=“HTTP/1.1 200 OK”+HTTPNewLine;
响应+=“服务器:TestServer 2020”+HTTPNewLine;
响应+=“内容类型:text/html;字符集=utf-8”+HTTPNewLine;
响应+=“内容长度:”+html.Length+HTTPNewLine;
响应+=HTTPNewLine;
响应+=html;
响应+=HTTPNewLine;
byte[]responseBytes=Encoding.UTF8.GetBytes(响应);
networkStream.Write(响应字节);
networkStream.Close();
tcpClient.Close();
}
公共无效侦听(Int32端口)
{
//Int32端口=12345;
IPAddress localaddr=IPAddress.Parse(“127.0.0.1”);
TcpListener TcpListener=新的TcpListener(localaddr,port);
tcpListener.Start();
//进入侦听循环(服务/守护进程)
while(true)
{
//@用于调试的同步版本
TcpClient TcpClient=tcpListener.AcceptTcpClient();
ProcessTcpClientAsync(tcpClient);
//tcpListener.AcceptTcpClientAsync().ContinueWith((res)=>ProcessTcpClientAsync(res.GetAwaiter().GetResult());
}
}
公共静态字节[]readByteBufferFromNetworkStream(NetworkStream NetworkStream)
{
字节[]缓冲区=新字节[256];
int字节读取=0;
while(true)
{
int currentBytesRead=networkStream.Read(buffer,bytesRead,buffer.Length-bytesRead);
字节读取+=当前字节读取;
//如果我们读取的数据少于缓冲区的大小->这意味着没有更多的信息,所以请中断。
if(currentBytesRead检查是否有更多信息,或者中断。
if(bytesRead==buffer.Length)
{
int nextByte=networkStream.ReadByte();
//河的尽头?如果是这样,我们就完了。
如果(下一字节==-1)
{
打破
}
//否则,请调整缓冲区大小,放入刚才读取的字节并继续。
其他的
{
byte[]newBuffer=新字节[buffer.Length*2];
复制(buffer,newBuffer,buffer.Length);
newBuffer[bytesRead]=(字节)下一个字节;
缓冲区=新缓冲区;
bytesRead++;
}
}
}
//缓冲区现在太大。请缩小它。
byte[]resultBuffer=新字节[bytesRead];
复制(缓冲区、结果缓冲区、字节读取);
返回结果缓冲区;
}
}
}

将标题与正文内容分开是此类响应标准的一部分

所有HTTP/1.1消息都由一个起始行和一个序列组成 以类似于Internet消息格式的格式显示的八位字节数
[RFC5322]:零个或多个标题字段(统称为
“标题”或“标题部分”),一个空行,表示
标题部分的结尾,以及可选的消息正文

 HTTP-message   = start-line
                  *( header-field CRLF )
                  CRLF
                  [ message-body ]

CRLF
以上将被视为
\r\n

我明白了,在请求2和3之间,我还应该有一些换行符。所以我没有正确读取网络流。
 HTTP-message   = start-line
                  *( header-field CRLF )
                  CRLF
                  [ message-body ]