我正在编写一个小型HttpServer,有时我遇到了丢失POST
数据的问题。
通过使用Wireshark,我发现Header
被分为two segments
。
我只得到第一个段(636个字节),第二个段(在这种情况下为POST数据)完全丢失。
这是相关的C#代码
string requestHeaderString = "";
StreamSocket socketStream = args.Socket;
IInputStream inputStream = socketStream.InputStream;
byte[] data = new byte[BufferSize];
IBuffer buffer = data.AsBuffer();
try
{
await inputStream.ReadAsync(buffer, BufferSize, InputStreamOptions.Partial);
// This is where things go missing, buffer.ToArray() should be 678 Bytes long,
// so Segment 1 (636 Bytes) and Segment 2 (42 Bytes) combined.
// But is only 636 Bytes long, so just the first Segment?!
requestHeaderString += Encoding.UTF8.GetString(buffer.ToArray());
}
catch (Exception e)
{
Debug.WriteLine("inputStream is not readable" + e.StackTrace);
return;
}
此代码属于StreamSocketListener
ConnectionReceived
Event
的一部分。
我是否需要手动重新组装TCP段,这不是系统TCP堆栈应该做的事情吗?
谢谢, 大卫
答案 0 :(得分:2)
问题是系统TCP堆栈像处理任何其他流一样处理TCP流。你没有得到"消息"使用流,您只需获得一个字节流。
接收方无法确定何时发出消息"结束,下一个开始的地方,你没有告诉它如何。您必须在TCP之上实现message framing,然后在接收方必须重复调用Receive
,直到您收到足够的字节来形成完整的消息(这将涉及使用返回的int
从接收调用中查看处理的字节数。)
重要说明:如果您不知道您希望获得多少字节,例如,您正在使用'\0'
分隔邮件进行邮件框架,则可能会收到一封邮件的结尾并在单个接收呼叫中开始下一个。你需要处理这种情况。
\r\n\r\n
,一旦你得到它你必须解析标题并解码HTTP消息的内容部分中有多少数据然后重复调用读取,直到你已经读取了数字需要的字节。