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

发布于 2024-11-26 13:03:21 字数 303 浏览 1 评论 0原文

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

命令

1stream.writestream.read

结构

命令

2stream.writestream.read

。 。 。

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

任何帮助将不胜感激

My application connects to a device and sends multiple commands across a single socket connection. It then reads the response to these the basic structure is

command 1

stream.write

stream.read

command 2

stream.write

stream.read

.
.
.

i am wondering if there is a better way of doing this. I am not worried about blocking because this is running on a different thread than the rest of the program. the problem i am encountering is that sometimes the data for command 1 lands in the read for command 2. The other thing is the 1st byte that i receive is unique to the command.

any help would be appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

再见回来 2024-12-03 13:03:21

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

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

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

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

Assuming TCP - there is no way to ensure that each command is read as it was sent. At the destination end, each command can be fragmented or joined to other commands, so you need to manually decide where the boundaries are between them.

A common technique is to prefix the commands with their length, which you can read first, and know precisely how many bytes to read before the next one. At the destination end, you usually have some kind of queue which you push all received data onto, and you read off the queue one command at a time, only when there is one or more completely received commands.

I wouldn't recommend using blocking sockets under any circumstances really, even if you're using a separate thread. If you need to both send and receive on the same socket, you could encounter issues where you attempt to call Read when no data is waiting, and you will not be able to send any data until some is received.

Rather than using the blocking calls, use BeginRead,EndRead for asynchronous receiving, then you'll be able to send and receive in the same thread without having those worries.

梦醒灬来后我 2024-12-03 13:03:21

因为您处于多线程中,所以在发送命令时使用锁定,例如:

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..}
}

Because you are in multithreading, use lock around sending commands, Like:

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

So only one command at time will send and receive data.

However, if you are receiving data from the device at any time "maybe it sends a notifications.." then consider do something like:

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

At 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..}
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文