我正在尝试创建一个可以处理多个客户端连接的套接字服务器,服务器代码如下:
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],仅在发送时,而不是在从客户接收数据时出现。
您可以看到失败是在回显之后。在socket_write($ read_sock,$ data); AND socket_write($ send_sock,$ data);
我听说这可能是与防火墙相关的问题,所以即使测试是在本地进行的,我也卸载了防病毒软件并完全删除了防火墙。
我尝试了两次与客户端的测试,一个测试是在写入后关闭套接字连接,然后读取,而另一个测试没有socket_close语句。
没有骰子,两个骰子上的错误相同。
我可能做错了什么?