Неблокирующий сокет в Windows не возвращается после вызова send () - PullRequest
2 голосов
/ 15 ноября 2009

Я надеюсь, что кто-то может объяснить ситуацию - любую ситуацию, - в которой неблокирующий сокет Windows не будет сразу возвращаться после использования send () для него. На других платформах мой код работает так, как задумано, поэтому, похоже, проблема связана с Windows.

Способ, которым я могу сказать, что он не возвращается, довольно прост: я cout отправляю сообщение непосредственно до и после функции send (), а после запуска консоль показывает только первое сообщение. Я не могу воспроизвести его в упрощенном примере, поэтому я прошу прощения за отсутствие кода. Я постараюсь предоставить больше подробностей, если это необходимо.

Edit:

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

SOCKET new_sock = accept(sock, (struct sockaddr*)&addr, &addr_size);

#ifdef _WIN32
    unsigned long ul;
    ioctlsocket(new_sock, FIONBIO, &ul);
#else
    fcntl(new_sock,F_SETFL,O_NONBLOCK);
#endif

setsockopt(new_sock, SOL_SOCKET, SO_LINGER, (unsigned char *)&lg, sizeof(lg));
setsockopt(new_sock, SOL_SOCKET, SO_OOBINLINE, (unsigned char *)&opt, sizeof(int));

Ответы [ 3 ]

1 голос
/ 16 ноября 2009

Передача заблокирует заполнение буферов ip-стека в подключенном сокете. Если у вас есть подключенный сокет, и вы начинаете кидать в него данные быстрее, то стек ip может выкрутить его по проводу с сопровождающими ack nak paddywacks, тогда отправка заблокируется.

Я не видел, чтобы правильно настроенные неблокирующие посылки блокировались. Они будут ошибки с блокировкой. Так что я бы посмотрел на то, как вы устанавливаете неблокирующий ввод. Вы уверены, что устанавливаете неблокирование на результирующем сокете, а не на базовом сокете ... т.е. сокете, возвращенном из accept.

1 голос
/ 16 ноября 2009

если это фактический код, вы не инициализировали ul . Есть:

unsigned long ul = 1;
ioctlsocket(new_sock, FIONBIO, &ul);
1 голос
/ 15 ноября 2009

Если ваш дисплей сообщений "cout" не содержит std :: endl, вызов может не блокироваться, если вы не заметите!

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