Коннект неблокирующего сокета

Wicked

Новичок
Коннект неблокирующего сокета

Чото не пойму :)

Хочется сделать на винде неблокирующий коннект сокета... поставил такой эксперимент:
PHP:
$winsockCodes = array(
  // Invalid Argument
  // An invalid argument was passed to a function.
  "WSAEINVAL" => 10022,
  // Resource Temporarily Unavailable
  // The specified socket operation cannot be completed immediately, but the operation should be retried later.
  "WSAEWOULDBLOCK" => 10035,
  // Socket is Already Connected
  // A connect request was made on a socket that is already connected. 
  "WSAEISCONN" => 10056,
  // Operation Already in Progress
  // An operation was attempted on a non-binding socket that already had an operation in progress.
  "WSAEALREADY" => 10037,
);

$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_nonblock($sock);
do {
  @socket_connect($sock,"api.facebook.com", 80);
  $err = socket_last_error($sock);
  echo $err, "\n";
} while($err !== $winsockCodes["WSAEISCONN"]);
выводит такие коды:
10035
10037
... // много
10037
10022 // иногда этого нету, раз на раз не приходится
10056

Как вообще это делать правильно?
Как правильно понимать, когда стоит дожидаться таймаута (в будущем), а когда соединение уже гарантированно не установится (10022, казалось бы, как раз такой случай)?
Как правильно сделать в будущем кросс-платформенность?

В мануале ничего по теме не нашел.
 

fixxxer

К.О.
Партнер клуба
с кодами ошибок известная засада. если в си все определено в header файлах, то тут разве что тупо подставлять нужные по OSNAME... ну или добавить патчик регистрирующий соответствующие php-константы =)

хотя может это уже и сделано. в последний раз года 3 назад с этим сталкивался, тогда ограничился FreeBSD и Linux :)
 

rotoZOOM

ACM maniac
Как это делается на Сях. Сначала как у тебя выполняется неблокирующий connect (аналог socket_connect). Затем, чтобы узнать, что соединение установилось, регулярно (а иначе зачем неблокирующий сокет) вызывать функцию select (аналог socket_select) и проверять пока данный сокет не будет готов для записи.
Но и это еще не все. После получения "добра" на запись обязательно вызови getsockopt (аналог socket_get_option) с флагом SO_ERROR и смотри, чтобы не было ошибки. И только после этого можно считать, что соединение установлено.
Естественно, в цикле коннект вызывать не нужно. :)
 

Wicked

Новичок
если в си все определено в header файлах
спасибо за идею :)

php-5.2.5\ext\sockets\win32_socket_constants.h
Код:
REGISTER_LONG_CONSTANT("SOCKET_EWOULDBLOCK", WSAEWOULDBLOCK, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SOCKET_EALREADY", WSAEALREADY, CONST_CS | CONST_PERSISTENT);
...
А по остальным вопросам есть мысли?

-~{}~ 30.04.08 21:16:

rotoZOOM
спасибо!
попробую - доложу :)
 
Сверху