我正在尝试用 C# 编写一个异步套接字。我阅读了很多 msdn 文章并找到了这两个示例:server , client .
我了解示例代码并使用它来实现我自己的异步套接字。在示例中,服务器检查 <EOF>
确定流的结尾并发送响应。我想知道流结束时不检查特殊文字。我的想法是检查 (bytesRead > 0)
并调用handler.BeginReceive()
递归地。
请参阅以下内容:
Original
if (bytesRead > 0) {
// There might be more data, so store the data received so far.
state.sb.Append(Encoding.ASCII.GetString(
state.buffer,0,bytesRead));
// Check for end-of-file tag. If it is not there, read
// more data.
content = state.sb.ToString();
if (content.IndexOf("<EOF>") > -1) {
// All the data has been read from the
// client. Display it on the console.
Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
content.Length, content );
// Echo the data back to the client.
Send(handler, content);
} else {
// Not all data received. Get more.
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReadCallback), state);
}
}
My idea
if (received > 0)
{
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, received));
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
}
else
Send(handler, state.sb.ToString());
如果我用我的部分替换原始部分,程序将停止运行。
我猜客户端执行 EndSend()
在SendCallback()
并在 receiveDone.WaitOne()
之后阻塞线程在StartClient()
.我怎么能通过这个?是否需要使用确定流结束的 token ?
还有其他好的示例代码吗?我刚找到那两个。
(证据。服务器应该接收在线客户端并将它们放入循环缓冲区,他应该使用多线程读取和处理记录。)
编辑
如果我使用以下内容:
if (receive > 0)
state.sb.Append(Encoding.UTF8.GetString(state.buffer, 0, receive));
if (receive == StateObject.BufferSize)
state.listener.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
else
Send(state.listener, state.sb.ToString());
我猜一切都很好。可以吗?还是想念什么?
如果我将这两个 if 结合起来,它就不会再起作用了。为什么?
if(receive > 0 || receive == StateObject.BufferSize)
-> if(receive > 0) // Not working.
最佳答案
您的代码版本的问题是您启动了 BeginReceive
总是,但在一种情况下,即当有 0
时收到的字节数。事实上,大多数情况下,当您收到的数据量不为零且小于缓冲区大小时(有时恰好是缓冲区大小时),传输就会结束。收货0
字节永远不会发生,因为这意味着没有传输而不是传输结束。这是假设发送方通过关闭连接来结束传输。
有多种方式来指示传输结束:
- 发送者关闭连接
- 发送特殊序列(如 EOF)
- 接收者得到了他所期望的(因为它首先得到了标题)
第一种方法的问题是关闭(和重新打开)连接通常很昂贵。
header 的问题是,如果您错过了一个 header (由于某些网络问题),您就迷路了——您不知道下一个 header 何时到来,因为您不知道当前数据包何时结束(丢失 header )。出现问题时最简单的恢复以某种形式提供 EOF。它不一定是字面上的 <EOF>
字符串,它可以是(很可能)永远不会出现在您的正常数据流中的任何东西。
话虽如此,没有什么可以阻止您将 header 与 EOF
结合使用或包含记录开始的特殊序列标记的 header 。
关于c# - 如何确定异步套接字服务器中的流结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15791769/