php - 正确使用 socket_select()

标签 php sockets packet

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

我连接到允许 TCP 和 UDP 数据包连接的服务器,我正在使用两者。在这些连接中,我在同一端口上发送和接收数据包,但 TCP 数据包将在一个端口 (29999) 上发送,而 UDP 数据包将在另一个端口 (30000)。传输类型将为 AF_INET。 IP 地址将环回 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?
}

最佳答案

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

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

如果 socket_select 返回 0,则表示套接字是非阻塞的,并且它们都没有任何可用数据。

HTH

C.

关于php - 正确使用 socket_select(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2591887/

相关文章:

php - 登录用户的 Yii 私钥

PHP "str_replace"在某些情况下无法正常工作?

php - 从指定日期php获取年份

java - 如何使用java套接字编程知道网络何时关闭

java - 当代码保持接受新套接字时,如何检查某些变量?

rawvideo 的 FFmpeg 标准输出数据包大小

javascript - 将php表单数据传输到js窗口

php - 通过php发送whatsapp消息

linux - 数据包在内核中的旅程如何?

linux - 存储网络数据包