3

所以我有一个普通的 PHP 套接字(或多或少与 php 手册中的示例代码相同)。我找到了一种方法来检测客户端何时断开连接(无论是否正常),但我如何识别它是谁?IP 地址的使用已停止,因为可能有多个用户使用相同的 IP。

提前致谢。

4

2 回答 2

3

如果您考虑TCP或 UDP 数据包标头中传递的内容,则其中包含的身份信息并不多,只有 IP 地址。如果您想知道客户的身份,您需要让他们发送某种唯一标识符(例如@madara 评论的用户名和密码)。如果它们来自同一个 IP,这意味着它们使用的是同一个路由器,在这种情况下,它的目的是掩盖路由器后面的设备。

要检测谁断开了连接,您首先需要确定谁连接了。每个连接都有自己的套接字,即使它们来自同一个 IP 地址。在伪 php 中:

// Store all active sockets in an array
$online_users = array();

// Open up a listening socket
$listener = socket_create(...);
socket_listen($listener);
$client_sock = socket_accept($listener);

// Have the client send authentication stuff after connecting and
// we'll receive it on the server side
$username = socket_read($client_sock, $len);
// Map the username to the client socket
$online_users[$username] = $client_sock;

// Continue to read or write data to/from the sockets. When a read or
// write fails, you just iterate through the array to find out who
// it was. If the socket $failed_sock failed, do as follows
foreach ($online_users as $name => $socket)
{
    if ($socket == $failed_sock)
    {
        // $name is the username of the client that disconnected
        echo $name . ' disconnected';
        // You can then broadcast to your other clients that $name
        // disconnected. You can also do your SQL query to update the
        // db here.
        // Finally remove the entry for the disconnected client
        unset($online_users[$name]);
    }
}
于 2012-09-26T19:43:10.907 回答
2

从逻辑上讲,在您的情况下,这很难!这里只是一个想法:

如果是聊天,如何将所有在线用户存储在数据库或具有以下列的平面文件中:

NICKNAME
IP
TIME

并创建一个函数来检查这些并相应地更新时间,比如说每 10 秒。基于此,您将能够确定何时以及谁在线/离线。

- - - 更新 - - -

检查您的套接字错误?使用 get_last_error() 检查错误代码。

$errorcode = socket_last_error(); 
$errormsg=socket_strerror($errorcode); 
die("Error: (".$errorcode.") ".$errormsg."\n");

取消设置用户:

if($data === FALSE) {
    socket_close($clients[$i]['socket']);
    unset($clients[$i]);
    echo 'Client disconnected!',"\r\n";
    continue;
}

从数据库中取消设置客户端。您还可以通过他们的 ID 从 $clients 数组中识别确切的昵称。

于 2012-09-26T19:51:21.383 回答