4

在 PHP 中使用 socket_select 发送和接收数据的正确方法是什么?

我有一个连接到允许 TCP 和 UDP 数据包连接的服务器的连接,我正在使用两者。在这些连接中,我在同一个端口上发送和接收数据包,但 TCP 数据包将在一个端口 ( 29999) 上发送,而 UDP 将在另一个端口 ( 30000) 上发送。传输类型将是AF_INET。IP 地址将是 loopback 127.0.0.1

我有很多关于如何在这种情况下创建套接字连接的问题。例如,是使用socket_create_pair建立连接更好,还是只使用socket_create后跟socket_connect,然后实现socket_select

有可能没有数据从服务器发送到客户端,由客户端来维持连接。这将通过使用 socket_select 调用中的超时函数来完成。如果在时间限制内没有发送数据,socket_select 函数将中断,然后可以发送一个保持活动数据包。以下脚本是客户端的。

// Create
$TCP = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$UDP = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);

// Misc
$isAlive = TRUE;
$UDPPort = 30000;
define('ISP_ISI', 1);

// Connect
socket_connect($TCP, '127.0.0.1', 29999);
socket_connect($UDP, '127.0.0.1', $UDPPort);

// Construct Parameters
$recv = array($TCP, $UDP);
$null = NULL;

// Make The Packet to Send.
$packet = pack('CCCxSSxCSa16a16', 44, ISP_ISI, 1, $UDPPort, 0, '!', 0, 'AdminPass', 'SocketSelect');

// Send ISI (InSim Init) Packet
socket_write($TCP, $packet);

/* Main Program Loop */
while ($isAlive == TRUE)
{
    // Socket Select
    $sock = socket_select($recv, $null, $null, 5);

    // Check Status
    if ($sock === FALSE)
        $isAlive = FALSE; # Error
    else if ($sock > 0)
        # How does one check to find what socket changed?
    else
        # Something else happed, don't know what as it's not in the documentation, Could this be our timeout getting tripped?
}
4

1 回答 1

1

我有点困惑 - 您似乎正在尝试处理通过 2 个套接字传入的异步请求,但两者都充当客户端?这是一个非常不寻常的场景。尝试使用不同的协议(tcp 和 udp)来实现它们甚至更奇怪(H323 VOIP 是我所知道的唯一应用程序)。一个快速的 google 建议您正在尝试为 LFS 编写客户端 - 但为什么您需要同时运行 TCP 和 UDP 客户端?(顺便说一句,他们在http://en.lfsmanual.net的 Wiki 上发布了合适的 PHP 客户端代码)

在调用 socket_select() 之后,有数据等待读取的套接字将位于 $recv 数组中(即数组被修剪并需要在 socket_select() 的下一次迭代之前重新填充)。

如果 socket_select 返回 0 它只是意味着套接字是非阻塞的并且它们都没有任何可用的数据。

高温高压

C。

于 2010-04-07T15:51:46.860 回答