socket_write () не может записать в сокет 10053 - PullRequest
0 голосов
/ 15 марта 2019

Я пытаюсь создать сервер сокетов, который может обрабатывать несколько клиентских подключений, код сервера следующий:

public function startWebServer()
{

    error_reporting(E_ALL);

    /* Permitir al script esperar para conexiones. */
    set_time_limit(0);


    $address = '127.0.0.1';
    $port = 25003;

    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);

    if ($socket === false) {
        echo "socket_create() falló: razón: " . socket_strerror(socket_last_error()) . "\n";
    }

    socket_bind($socket, $address, $port) or die ("Error al vincular socket con IP de cliente)\n" . socket_strerror(socket_last_error($sock)) . "\n");


    socket_listen($socket) or die ("Error al vincular socket con IP de cliente) SOCKET LISTEN \n" . socket_strerror(socket_last_error($sock)) . "\n");;


    $clients = array($socket);

    do 
    {
        // create a copy, so $clients doesn't get modified by socket_select()
        $read = $clients;
        $write = null;
        $except = null;

        // get a list of all the clients that have data to be read from
        // if there are no clients with data, go to next iteration
        if (socket_select($read, $write, $except, 0) < 1)
            continue;

         // check if there is a client trying to connect
        if (in_array($socket, $read))
        {
            $clients[] = $newsock = socket_accept($socket);

            socket_write($newsock, "There are ".(count($clients) - 1)." client(s) connected to the server\n");

            socket_getpeername($newsock, $ip, $port);

            echo "New client connected: {$ip}\n";
            $key = array_search($socket, $read);

            // remove the listening socket from the clients-with-data array
            unset($read[$key]);
        }

         // loop through all the clients that have data to read from         

        foreach ($read as $read_sock)
        {
            // read until newline or 1024 bytes

            // socket_read while show errors when the client is disconnected, so silence the error messages
            $data = @socket_read($read_sock, 4096, PHP_BINARY_READ);

            // check if the client is disconnected
            if ($data === false)
            {
                // remove client for $clients array
                $key = array_search($read_sock, $clients);
                unset($clients[$key]);
                echo "client disconnected.\n";
                continue;
            }

            $data = trim($data);

            if (!empty($data))
            {
                echo " send {$data}\n";
                // do sth..
                // send some message to listening socket
                socket_write($read_sock, $data);

                // send this to all the clients in the $clients array (except the first one, which is a listening socket)
                foreach ($clients as $send_sock)
                {
                    if ($send_sock == $socket)
                        continue;

                    socket_write($send_sock, $data);

                } // end of broadcast foreach
            }
        } // end of reading foreach



    } 
    while (true);

    socket_close($socket);
}

В другом тесте, который я сделал, управляя только одним клиентом, все получилось нормально:

 while(true)
{
    $client[++$i] = socket_accept($socket);
    $message = socket_read($client[$i],1024);
    echo $message;
    $message = "Hola" . $message . "\n";
    socket_write($client[$i], $i . " " . $message . "\n\r", 1024);
    socket_close($client[$i]);
}

В первом случае, когда я пытаюсь написать своим клиентам, я получаю сообщение об ошибке [10053], только при отправке, а не при получении данных от моих клиентов.

Failure to write to clients

Как видите, сбой происходит после эха. На socket_write ($ read_sock, $ data); AND socket_write ($ send_sock, $ data);

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

Я попробовал два теста с клиентом: один закрыл соединение с сокетом после записи, затем прочитал, а другой без оператора socket_close.

Без кубиков, одна и та же ошибка на обоих.

Что я мог делать не так?

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