Сокет PHP принудительно закрывается клиентом

Я создал сервер сокетов PHP. Я подключился к нему с помощью telnet или putty, и все работает просто отлично, пока я не попытался подключиться к приложению .Net, каждый раз, когда я запускаю приложение, он закрывает сервер, вот мой код C#, всего две строки:

System.Net.Sockets.TcpClient cli = new System.Net.Sockets.TcpClient("192.168.0.200", 10000);
cli.Close();

Когда я запускаю приложение, сервер сокетов PHP закрывается с этой ошибкой:

Warning: socket_read(): unable to read from socket [0]: An existing connection was forcibly closed by the remote host

Я попытался закомментировать строку Cli.close(), и, конечно же, сокет оставался открытым до тех пор, пока приложение С# не было закрыто, а затем оно закрывалось с тем же сообщением об ошибке, что и выше.

Итак, что вызывает проблему? Клиент не должен иметь возможность закрыть сокет таким образом.

Спасибо


person AL-Kateb    schedule 23.04.2015    source источник
comment
Можете дать php-код, отвечающий за чтение сокета?   -  person Stepashka    schedule 23.04.2015
comment
Он точно такой же, как и в примере руководства php.net/manual/en/ sockets.examples.php   -  person AL-Kateb    schedule 23.04.2015
comment
В чем твоя проблема? Что вы ожидаете, если клиент закроет соединение? Если вы подключаетесь с помощью telnet/putty и УБИВАЕТЕ соединение, закрывая telnet/putty с помощью диспетчера задач (то есть, не вводя quit или shutdown в telnet/putty), вы получаете другое поведение?   -  person nl-x    schedule 23.04.2015
comment
@nl-x в приложении .Net, когда клиент закрывает соединение, он не просто отключает соединение клиента, он также закрывает сервер соединений, в то время как при использовании шпатлевки или Microsoft telnet выход или даже закрытие клиентского приложения принудительно не делайте то же самое, сокет остается открытым в ожидании будущих клиентов   -  person AL-Kateb    schedule 23.04.2015


Ответы (1)


Посмотрите код на http://php.net/manual/en/sockets.examples.php Я не вижу в этом никаких проблем. Этот код существует в сценарии, когда сокет закрыт:

if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
        echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n";
        break 2;
    }

Что я могу предложить, так это изменить код следующим образом:

if (false === ($buf = @socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
        echo "socket_read() failed: reason: " . socket_strerror(socket_last_error($msgsock)) . "\n";
        break;
    }

Добавление '@' предотвратит появление предупреждения. Изменение break 2; на break; заставит сервер не выходить, а продолжать ждать следующего соединения.

Если это не сработает, вы можете перенести весь скрипт в другой цикл do { } while(), чтобы каждый раз, когда чтение сокета завершалось неудачно, php выполнял socket_create() снова.

person Stepashka    schedule 23.04.2015
comment
Это решение работает, но я чувствую, что это не способ сделать это, я все еще получаю сообщение об ошибке (если я не подавляю его с помощью @), что, я считаю, не должно иметь место, но я могу отправить выход, когда приложение закрыт в приложении .Net для решения этой проблемы, спасибо - person AL-Kateb; 23.04.2015
comment
Предупреждение — это нормальное поведение для socket_read, хотя и не самое лучшее. В рабочей среде вы можете отключить предупреждения, выполнив что-то вроде этого stackoverflow.com/questions/332178/ . Удачи. - person Stepashka; 23.04.2015
comment
дело в перерыве 2, перерыв 2 относится к перерывам. который закрывает if и do while - person jaafar Nasrallah; 26.09.2018