Здравствуйте. Объясните пожалуйста принцип работы с сокетами, в частности с протоколом TCP, на таком примере: Код (PHP): $socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP); socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => 3, 'usec' => 0)); socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, array('sec' => 3, 'usec' => 0)); socket_connect($socket,"192.168.100.100",9900); $n = microtime(true); while (socket_recv($socket, $t, 8192, 0)) { var_dump($t); } echo "mt: ".(microtime(true)-$n)."\n"; У меня получается, что цикл выполняется дважды один раз получает данные(меньше чем указан размер буфера), второй раз пока не истечет таймаут(потому что время выполения скрипта больше 3сек). Почему socket_recv не завершается, если в сокете ничего нет? Или я должен точно знать до байта, размер информации которую мне отправит сервер? Или я должен сравнивать размер буфера кол-вом прочитанных байт, и если данных меньше чем размер буфера, то данные кончились? PHP, JavaScript, SQL и другой код пишите внутри тегов Код ( (Unknown Language)): [b]php][/b]Тут код[b][/[/b][b]code][/b][/color]
Так в этом и смысл таймаута в TCP. Данные по TCP передаются пакетами. Какой-нибудь очередной пакет может не дойти, условно говоря, 100 раз подряд. В это время твой сокет на другом конце будет стоять пустым и ждать данные, пока не истечет таймаут. Сокет TCP не должен закрываться лишь по тому, что закончились данные в этот момент. Он предполагает двухсторонний обмен, поэтому без специальных условий ни одна сторона не должна его закрывать. Например, если ты принимаешь данные HTTP, то ты должен распарсить заголовок Content-Length и читать заданное количество байтов, после чего закрыть сокет вручную. А если заголовка нет, то закрыть сокет после двух пустых строк. Или сначала отправить ответ, а потом закрыть сокет.