PHP:socket侦听问题

时间:2009-04-07 18:13:46

标签: php sockets

这是我的代码:

<?php

$host = "127.0.0.1";
$portListen = 1234;
$portSend = 1240;


// create socket
$sSender = socket_create(AF_INET, SOCK_STREAM, 0);

socket_connect($sSender, $host, $portListen);

socket_write($sSender, "test", strlen ("test"));


$sListen = socket_create(AF_INET, SOCK_STREAM, 0);
socket_set_option($sListen, SOL_SOCKET, SO_REUSEADDR, 1);

socket_bind($sListen, $host, $portSend);

socket_listen($sListen,1);
$dataSock = socket_accept($sListen);
echo socket_read($dataSock, 3, PHP_NORMAL_READ);

// close sockets
socket_close($sSender);
socket_close($sListen);
?>

我将“test”发送到另一个应用程序,它接收并发回“ack”。问题是,我只能这样做一次。如果我刷新,我得到的地址已经使用错误。我尝试了在php.net上建议的解决方案,但无济于事。尝试在socket_close()之前使用socket_shutdown()只会给我一些未连接的警告,并且在刷新时会给我一个永无止境的加载。

根据我的理解,套接字没有立即关闭的原因是因为缓冲区中仍有数据。但是你可以看到我明确表示只听一个连接。另外,我只从我的应用程序中发送3个字符,并在此脚本中读取3个字符。

我做错了什么?

编辑:我使用2个套接字的原因是因为我在write()之后无法监听(),这给了我套接字已经连接错误。在write()之后跳过listen()并直接读取read()会给我带来无效的参数错误。

3 个答案:

答案 0 :(得分:2)

我看到,经过几个小时的睡眠并重新分析我的代码和文档后,我设法解决了所有问题。你们是对的,1个插槽确实足够和正确的方式:

<?php

$host = "127.0.0.1";
$portListen = 1234;
$sSender = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");

socket_connect($sSender, $host, $portListen) or die("Could not connect\n");

socket_write($sSender, "test", strlen ("test")) or die("Could not write output\n");

echo socket_read($sSender, 3, PHP_NORMAL_READ);

socket_close($sSender);
?>

这么简单!

答案 1 :(得分:1)

为什么需要创建2个用于读写的套接字?它看起来像一个奇怪的设计。客户端应用程序通常打开与服务器的套接字连接,然后发送请求并在同一套接字上读取服务器的响应。 此外,创建侦听套接字(低于服务器)将无法扩展到任何防火墙或NAT网关。

回答你的评论:不需要听。只是阅读(如果您的服务器尚未回复,可能会阻止操作)。

答案 2 :(得分:1)

连接关闭后,套接字进入延迟状态,以便在(关闭期间)数据包丢失并重新传输时,响应将是一个干净的确认,而不是RST(重置),表示没有这样的套接字是公开的。它是TCP规范的一部分,你不能让它停止发生。

Listen(1)并不意味着只接受一个连接,它意味着维护一个连接的队列,等待一个应用程序accept()。因此,只要您接受第一个,套接字就可以收听更多内容了。

和其他人一样,我想知道为什么奇怪的设计,但我认为这是一个简单的例子,它提出了你的问题,并不一定能提出你的真实计划。