2012-01-31 2 views
0

Я работаю над написанием TCP-сервера с использованием Berkeely SOCKET API под Linux. Теперь у клиентов есть набор спецификаций, и каждое сообщение, отправленное клиентом, основано на тех спецификациях. I-e сообщение, отправленное с клиента, соответствует одной из многих структур, указанных спецификациями. Теперь сценарий заключается в том, что сервер не знает, какое сообщение клиент отправит в какое время. Как только мы получим сообщение, мы сможем выяснить, что это такое, но не до этого. Сообщения, отправленные клиентами, имеют переменную длину, поэтому мы не можем заранее знать, какое сообщение мы собираемся получить. Чтобы решить эту проблему я использовал следующий метод:Как правильно использовать recv() sys call

const char *buf[4096] = { 0 }; 
      if (recv (connected, buf, 4096, 0) == -1) 
      { 
       printf ("Error in recvng message\n"); 
       exit (-1); 
      } 

То есть я использую буфер по умолчанию размером 4096 (никакое сообщение от клиента не может быть больше, чем этот размер). получить в этом буфере, а затем после этого я Проверьте тип сообщения и принять соответствующее действие следующим образом:

struct ofp_header *oph; 
oph=(struct ofp_header *)buf; 
switch (oph->type) 
{ 
case example_pkt: 
handle_example_pkt(); 
break; 
} 

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

Спасибо.

ответ

5

TCP основан на потоке. Это означает, что если вы используете буфер больше, чем ваше сообщение, вы также можете получить часть следующего сообщения.

Это означает, что вам нужно будет узнать размер сообщения и включить любые дополнительные данные в следующее сообщение. Есть два очевидных способа сделать это:

  1. Изменить протокол, чтобы отправить размер каждого сообщения в виде первых нескольких байтов сообщения. Сначала прочтите размер, а затем прочитайте только то, что много байтов.

  2. Поскольку вы знаете размер каждого сообщения, отслеживайте, сколько байтов вы читаете. Обработайте первое сообщение в буфере, а затем вычтите размер этого сообщения из оставшихся байтов в буфере. Продолжайте повторять этот процесс до тех пор, пока не будете либо A. Недостаточно байт для идентификации типа сообщения или B. Недостаточно байтов для сообщения об обнаруженном типе. Сохраните оставшиеся байты и снова вызовите recv, чтобы прочитать больше данных.

+0

Да, это то, чего я боюсь. Можете ли вы отправить решение? – Abdullah

+0

См. Отредактированный ответ. –

+0

Большое спасибо, теперь понятно, что делать :) cheers :) – Abdullah

 Смежные вопросы

  • Нет связанных вопросов^_^