我当前的ClientHandler
方法收到TcpClient
,在该客户端上打开NetStream
,并开始从中提取数据:
try
{
//byte[] bytes = new byte[client.ReceiveBufferSize];
byte[] bytes = new byte[100];
int bytes_read = netstream.Read(bytes, 0, bytes.Length);
Console.WriteLine(DateTime.Now.ToString() + ": Bytes Read");
while ( bytes_read > 0)
{
memstream.Write(bytes, 0, bytes_read);
bytes_read = netstream.Read(bytes, 0, bytes.Length);
if (memstream.Length > 255)
{
MemStreamRead(memstream);
memstream.Flush();
OkResponse(netstream);
}
}
}
catch (Exception e)
{
Console.WriteLine("No longer connected");
connected = false;
Console.WriteLine(e);
Console.WriteLine(e.StackTrace);
}
我已经可以从客户端获取第一条消息了,但是我很难想到如何保持流为新消息打开,并决定当前消息何时完成。
netstream.DataAvailable
似乎可以正常工作,我假设它检测到netstream
何时不再获取更多数据,并返回false。但是,一旦有新数据,我该如何开始再次收听?
提前感谢您的帮助!
答案 0 :(得分:2)
将TcpClient
对象及其netstream
保留在可以反复使用的位置。然后根据需要经常调用netstream.Read()
(非阻塞)。 DataAvailable
会告诉您何时有数据需要阅读。
注意:传入的TCP数据被添加到一个大缓冲区中,并且在收到时无法分离回数据包。
以足够大的尺寸拨打Read()
将获得所有'来自缓冲区的数据
您将需要自己的更高级别协议来分隔它。易于实施......
另一方面,在UDP上,Read()
将返回1个数据包的数据。在Read()
之后,将返回下一个数据包的数据。分组结构'保留。
对于TCP更高级别的协议,您可以这样做:
修改强>:
进一步通知:
如果远程端关闭连接,Read()
仍将成功执行,但不会返回数据。您必须以另一种方式找出连接是否即将关闭。有关更多有用的信息,请参阅我在其他SO网络问题上的答案。
答案 1 :(得分:1)
一旦有新数据,我该如何重新开始听?
再次致电Read
。这就是大多数循环的工作方式,只需在专用线程上调用非阻塞Read
(或阻塞Read
),并在获取数据时进行处理。
当我的当前消息完成时
这是你的另一个问题。当操作系统套接字缓冲区中没有更多数据时,您的消息不一定完成,当您按照规则定义完成时,它就完成了。您通常使用消息长度打开消息,然后继续向操作系统询问数据,直到您填充给定长度的缓冲区(或由于超时而失败)。