开发者

how to do multiple stream.writes and reads on a single socket

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

comma开发者_运维知识库nd 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


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.


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜