c# Http服务器使用StreamSocketListener,选项"InputStreamOptions.
本文关键字:选项 quot InputStreamOptions StreamSocketListener Http 服务器 | 更新日期: 2023-09-27 18:10:29
首先我正在做一个Windows Universal应用项目。我使用StreamSocketListener
创建了一个简单的tcp侦听器。数据来自一个连接到我本地网络的设备。该设备随机发送Http和Http/Xml报文。
StreamSocketListener listener = new StreamSocketListener();
public async void HttpServer()
{
listener.ConnectionReceived += (s, e) => ProcessRequestAsync(e.Socket);
HostName hostName = new HostName("192.168.0.150");
NetworkAdapter thisAdapter = hostName.IPInformation.NetworkAdapter;
await listener.BindServiceNameAsync("5400", SocketProtectionLevel.PlainSocket, thisAdapter);
}
当数据可用时,这是回调函数:
private const uint BufferSize = 12000;
private async void ProcessRequestAsync(StreamSocket socket)
{
StringBuilder request = new StringBuilder();
using (IInputStream input = socket.InputStream)
{
byte[] data = new byte[BufferSize];
IBuffer buffer = data.AsBuffer();
uint dataRead = BufferSize;
while (dataRead == BufferSize)
{
await input.ReadAsync(buffer, BufferSize, InputStreamOptions.None);
request.Append(Encoding.UTF8.GetString(data, 0, (Int32)buffer.Length));
dataRead = buffer.Length;
}
String message = request.ToString();
ExampleTextLabel.Text = message;
....
}
问题是:
我已经设置BufferSize = 12000。这是因为,到目前为止,我收到的最大数据长度低于11500。内容的长度是在HTML标题(content - length),但我不确定如何阅读标题前行:
await input.ReadAsync(buffer, BufferSize, InputStreamOptions.None);
当我使用InputStreamOptions选项时。没有,我收到的消息延迟一个包。换句话说,当设备发送数据包1时,它不会将其写入以下文本标签:
ExampleTextLabel.Text = message;
当数据包2到达时,ExampleTextLabel显示来自数据包1的消息。我知道这一点,因为我正在使用Wireshark来观察传入的数据包。
另一方面,如果我使用InputStreamOptions。部分,没有延误。我收到的数据包显示在Wireshark中。然而,这种解决方案的问题是,大多数时候数据包是损坏的(不完整的)。
谁能给我解释一下这里的问题,有没有什么解决办法?谢谢!
回答我的问题
InputStreamOptions。Partial是指异步读操作在有一个或多个字节可用时完成。
这意味着有时它会在没有完成数据包的情况下结束读取操作。我对上面的代码做了以下更改以使其工作(不是实际的代码,只是给出想法的注释):
while (allDataRead)
{
await input.ReadAsync(buffer, BufferSize, InputStreamOptions.None);
request.Append(Encoding.UTF8.GetString(data, 0, (Int32)buffer.Length));
dataRead = buffer.Length;
//make sure the data read contains the html header, otherwise loop again
//until you can extract the HTML header.
//Get the content length from the HTTP header.
//If the buffer size does not match the content length + html header length,
//then loop again to get the remaining packets until the buffer length
//matches the content length + html header length
//If the content length matches the buffer length then you have received the packet completely.
//allDataRead=true to exit the loop.
}