Определите, остались ли Данные в сокете, и отбросьте их. - PullRequest
1 голос
/ 04 августа 2011

Я пишу интерфейс под Linux, который получает данные из сокета TCP.Пользователь предоставляет буфер, в котором хранятся полученные данные.Если предоставленный буфер слишком мал, я просто хочу вернуть сообщение об ошибке.Первая проблема состоит в том, чтобы определить, был ли буфер малым.Функция recv () просто возвращает мне количество байтов, фактически записанных в буфер.Если я использую флаг MSG_TRUNC, указанный на man-странице recv (), он все равно возвращает мне то же самое.Вторая проблема - сбросить данные, все еще находящиеся в очереди в сокете.Так что, если я решу, что мой предоставленный буфер был маленьким, я просто хочу стереть все, что осталось в сокете.Есть ли другие способы сделать это, кроме как снова закрывать и открывать сокет или просто получать, пока ничего не останется?С наилучшими пожеланиями <</p>

Одним из предложений было просто восстановить до тех пор, пока ничего не останется (я получаю 0) - но не закончится ли это необходимостью ожидания установленного времени ожидания (в данном случае это 5 секунд?), Потому что каждый разпозвонить в recv, он ждет данных или тайм-аут?

Ответы [ 2 ]

4 голосов
/ 04 августа 2011

На уровне TCP нет сведений о том, что составляет сообщение протокола приложения.Однако существует два наиболее распространенных способа разграничения сообщений в потоке TCP:

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

В этом свете универсальный считыватель TCP должен обеспечить две универсальные функции чтения, которые будут универсально полезны:

  • для чтения N байтов и
  • читать до тех пор, пока не будет прочитан разделитель

Конструкция, аналогичная функциям чтения Tornado IOStream , подойдет.

1 голос
/ 04 августа 2011

У вашего дизайна есть недостаток.

Если клиент предоставляет слишком маленький буфер, как вы узнаете, сколько данных нужно отбросить?Есть ли в данных что-то, что говорит вам, когда вы достигли конца сообщения, которое нужно удалить?Если это так, то вам нужно буферизовать входной поток в вашем коде, чтобы вы могли обнаружить эти границы.Если ваш код видит поток как недифференцированные байты, тогда ваш вопрос не имеет смысла, поскольку ваш код в принципе не может знать, когда прекратить отбрасывать данные.С потоками TCP, если нет встроенного протокола, который разделяет «сообщения», то все или ничего до тех пор, пока соединение не будет закрыто.

...