Почему сокет не переходит в неблокирующий режим?

Я пытаюсь установить свой сокет в неблокирующий режим, используя ioctlsocket, но он возвращает -1, а WSAGetLastError возвращает 10045 - Операция не поддерживается. Почему такое могло случиться?

Код, который я пишу, довольно специфичен, потому что это не C ++, а Lisp с интерфейсом иностранного языка (он позволяет вызывать функции C и C ++ из dll), но на самом деле это не имеет значения, потому что все остальное работает.

Вот код:

(defconstant FIONBIO #x5421)
(setf socket-descriptor (socket AF_INET SOCK_STREAM IPPROTO_TCP))
...
(fli:with-dynamic-foreign-objects ((no-block (:unsigned :long) :initial-element 1))
  (ioctlsocket socket-descriptor FIONBIO no-block))
...

socket-descriptor - это просто дескриптор сокета, созданный стандартной функцией socket

FIONBIO - константа, я нашел ее значение, просто погуглил

no-block - указатель на u_long, значение th u_long 1.

ioctlsocket возвращает -1, а WSAGetLastError возвращает 10045.


person TheEnt    schedule 24.04.2013    source источник


Ответы (1)


Если это вообще помогает, ошибка 10045, которую вы получаете от WSAGetLastError, описывается следующим образом:

введите описание изображения здесь

ИЗМЕНИТЬ
В моей системе Windows я проверил значение FIONBIO в отладчике, и оно должно быть 0x8004667E.

Это определено так в winsock.h и winsock2.h в Windows 8 SDK:

#define _IOW(x,y,t)  (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y))
#define FIONBIO      _IOW('f', 126, u_long) /* set/clear non-blocking i/o */

Если вы установите unsigned int равным FIONBIO, то получите 0x8004667E.

person Roger Rowland    schedule 24.04.2013
comment
Спасибо, я прочитал это, но до сих пор не могу понять, что случилось. - person TheEnt; 24.04.2013
comment
Да, это обычно полезное описание MS, но оно, кажется, указывает на то, что есть какое-то свойство или состояние сокета, которое необходимо, прежде чем вы сможете сделать его неблокирующим. Я обновлю ответ, если найду больше подсказок. - person Roger Rowland; 24.04.2013
comment
OMG, большое спасибо, это работает! У меня была идея, что FIONBIO может быть неправильным, но я не мог найти другое возможное значение. - person TheEnt; 24.04.2013
comment
Я проверил значение FIONBIO в отладчике, и оно должно быть 0x8004667E. Это почти так же маловероятно, как и получается. Это будет однобитовое значение. - person user207421; 24.04.2013
comment
@EJP - Только что пояснил мои источники в редактировании, это может быть маловероятно, но так оно определено и решило проблему OP. Это просто Winsock? - person Roger Rowland; 24.04.2013