如何在单个套接字上执行多个stream.writes和读取

时间:2011-07-23 23:38:49

标签: c# .net sockets stream

我的应用程序连接到设备并通过单个套接字连接发送多个命令。然后它读取对这些基本结构的响应

命令1

stream.write

stream.read

命令2

stream.write

stream.read

。 。

我想知道是否有更好的方法。我不担心阻塞,因为它运行在与程序其余部分不同的线程上。我遇到的问题是,有时命令1的数据落在命令2的读取中。另一个是我收到的第一个字节对命令是唯一的。

任何帮助将不胜感激

2 个答案:

答案 0 :(得分:0)

假设TCP - 无法确保每个命令在发送时都被读取。在目标端,每个命令都可以分段或连接到其他命令,因此您需要手动确定它们之间的边界。

一种常见的技术是在命令前加上它们的长度,您可以先读取它们,并准确地知道在下一个字节之前要读取的字节数。在目的端,您通常会有某种队列将所有接收到的数据推送到队列中,并且只有在有一个或多个完全接收到的命令时才会一次读取队列中的一个命令。

即使您使用的是单独的线程,我也不建议在任何情况下都使用阻塞套接字。如果您需要在同一个套接字上发送和接收,则可能会遇到在没有数据等待时尝试调用Read的问题,并且在收到某些数据之前您将无法发送任何数据。

使用BeginReadEndRead进行异步接收,而不是使用阻塞调用,然后您就可以在同一个线程中发送和接收,而不必担心这些问题。

答案 1 :(得分:0)

因为您处于多线程状态,所以请使用锁定发送命令,例如:

public void SendCommand(Command command)
{
    lock (_commandLocker)
    {
       stream write
       stream read 
    }
}

因此,只有一个命令会发送和接收数据。

但是,如果您在任何时间从设备接收数据“可能会发送通知......”,请考虑执行以下操作:

private Queue<Notification> _notificationsBuffer = new Queue<Notification>();//Or use BlockingCollection if your are using 4.0

SendCommand

...
while (stream read)
{
    if (this is a notification)
    {
     then add it to the notification buffer and continue read
     continue;
    }
    else (this is our command)
    { ... read the response..}
}