2010-10-29 3 views
0

Я работаю над проектом, где партнер предоставляет услугу в качестве сервера сокетов. И я пишу клиентские сокеты для связи с ним. Сообщение имеет два направления: я отправляю запрос на сервер, а затем получаю ответ от сервера.Клиентский сокет отправляет данные, но серверный сокет не получает их. C++ буферизованный поток?

Проблема в том, что я отправляю данные на сервер, но, по-видимому, сервер не может получить данные.

С моей стороны я просто использовать очень простую реализацию так же, как, например, из http://www.linuxhowtos.org/C_C++/socket.htm

#include <sys/socket.h> 

socket_connect(); 

construct_request_data(); 

send(socket, request_data, request_length, 0/*flag*/); // I set flag as 0 

// now the server should receive my request and send response to me  

recv(socket, response_data, response_length, 0); 

socket_close(); 

И, кажется, что сокет сервера осуществляется с «обязательным» для STD :: iostream и буферизуется поток , (То есть гнездо посыла/RECV делается в iostream :: записи/чтения.)

server_socket_io >> receive_data; 

server_socket_io << response_data; 

Btw, я получил тестовый клиент от своего партнера, и он обернут в iostream, а также. Клиент тестового сокета может без проблем общаться с сервером, но он должен делать iostream :: flush() после каждого сокета.

Но я хочу просто просто не обернуть мой сокет-клиент в iostream.

Мне просто интересно, возникает ли проблема с буферизацией iostream: данные не обрабатываются, поскольку данные, отправленные клиентским сокетом, находятся в очень небольшом количестве и все еще буферизованы.

Или это может быть проблемой? как я могу узнать, действительно ли я отправляю данные? мой клиентский сокет также буферизует данные?

Я пробовал некоторое «плохое» обходное решение с TCP_NODELAY, но это не помогло!

Как я могу решить проблему? с клиентской стороны? или на стороне сервера? Должен ли я закрыть сокет после отправки запроса и до получения ответа, чтобы данные были «сброшены» и обработаны?

или должен ли я обернуть мой сокет в iostream и сделать флеш?

или серверный сокет должен использовать «небуферизованный» поток?

благодарит за любые предложения и советы!

+0

Как 'recv' и' send' являются низкоуровневыми функциями, которые дают вам полный контроль над данными, передаваемыми по вашему сокету, не должно быть ничего, чего вы не можете достичь с помощью. Не зная тип 'server_socket_io',' receive_data' и 'response_data', невозможно точно знать, как они форматируют данные и не видя содержимого буфера, который вы отправляете с помощью' send', невозможно узнать, какие материальные различия там находятся между двумя реализациями. Можете ли вы опубликовать код, который показывает различия? –

ответ

3

В ответ на ответ Джея вы можете попробовать любой сетевой сниффер и проверить, попадают ли ваши пакеты на сервер или нет. Посмотрите на wirehark или tcpdump.

+0

Серверная сторона обертывает сокет iostram и streambuf, и в начале меня беспокоило, что streambuf :: underflow() может быть неправильно реализовано. Затем я использовал wirehark для мониторинга пакетного трафика и обнаружил, что клиент действительно отправил пакеты, и сервер также должен их получить. И вдруг я заметил, что пакет, посланный клиентом, был каким-то другим, как и должно быть (против определенного протокола), тогда я легко решил проблему, что я просто отправил неправильное содержимое пакета, и сервер не смог его распознать (и, следовательно, не обрабатывать Это). – elgcom

+0

Это был простой провал! это даже не о сокетной штуке! Но использование wirehark или tcpdump для изучения пакетов всегда является хорошей идеей для сужения проблемы. Поэтому я даю ваше предложение в моей ситуации в качестве ответа: P – elgcom

+0

@elgcom Рад быть полезной. – Himanshu

0

Вы должны проверить настройки брандмауэра для обеих систем. Они не могут передавать ваши данные.

+0

, что не может быть проблемой. Я проверил. – elgcom

2

Давайте использовать «разделить и победить», чтобы решить эту проблему.

Во-первых, работает ли сервер?

Из вашего кода найдите номер порта, который слушает ваш сервер.

Запустите программу своего сервера. Выполните следующую команду строки программы, чтобы увидеть, если сервер действительно слушает:

NetStat -an -p TCP

Он будет производить список соединений. При запуске сервера вы должны увидеть соединение на выбранном порту. Остановите сервер и запустите команду еще раз, чтобы убедиться, что порт больше не используется.

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

телнета вашего-сервер-адреса здесь своего порт-номер-вот

телнета напечатает что ваш сервер отправляет вам на экран и отправляет то, что вы набираете обратно на сервер.

Это должно дать вам хорошие подсказки.

1

У меня была аналогичная проблема раньше. Моя проблема заключалась в том, что я никогда не «принимал» соединение (TCP) на сервере inorder для создания потока между сервером/клиентом. После того, как я принял соединение на стороне сервера, все работало так, как было разработано.

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