как сделать несколько потоков. пишет и читает на одном сокете - PullRequest
0 голосов
/ 24 июля 2011

Мое приложение подключается к устройству и отправляет несколько команд через одно сокетное соединение. Затем он читает ответ на эти основные структуры

команда 1

stream.write

stream.read

команда 2

stream.write

stream.read

. , .

Мне интересно, есть ли лучший способ сделать это. Я не беспокоюсь о блокировке, потому что она работает в другом потоке, чем остальная часть программы. проблема, с которой я сталкиваюсь, заключается в том, что иногда данные для команды 1 попадают в команду чтения для команды 2. Другая вещь - это 1-й байт, который я получаю, является уникальным для команды.

любая помощь будет оценена

Ответы [ 2 ]

0 голосов
/ 24 июля 2011

Поскольку вы используете многопоточность, используйте блокировку при отправке команд, например:

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..}
}
0 голосов
/ 24 июля 2011

Предполагается, что TCP - нет способа гарантировать, что каждая команда будет прочитана так, как она была отправлена.В конце пункта назначения каждая команда может быть фрагментирована или присоединена к другим командам, поэтому вам нужно вручную решить, где находятся границы между ними.

Обычный метод - это префикс команд с их длиной, которую вы можетесначала прочитайте, и точно знаете, сколько байтов нужно прочитать до следующего.В конце пункта назначения у вас обычно есть какая-то очередь, в которую вы помещаете все полученные данные, и вы читаете по очереди одну команду за раз, только когда есть одна или несколько полностью полученных команд.

Iне рекомендую использовать блокирующие сокеты ни при каких обстоятельствах, даже если вы используете отдельный поток.Если вам нужно и отправлять, и получать по одному и тому же сокету, вы можете столкнуться с проблемами, когда вы пытаетесь вызвать Read, когда нет данных, ожидающих, и вы не сможете отправлять какие-либо данные, пока некоторые не будут получены.Вместо того, чтобы использовать блокирующие вызовы, используйте BeginRead, EndRead для асинхронного приема, тогда вы сможете отправлять и получать в одном потоке, не беспокоясь об этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...