Php Can';无法从套接字读取数据(挂起)

Php Can';无法从套接字读取数据(挂起),php,c++,sockets,Php,C++,Sockets,我使用PHP连接到本地C++ socket服务器,以保持Web应用程序和几个守护进程之间的状态。我可以向套接字服务器发送数据,但不能从它接收数据;它只是阻塞socket\u read()并无限期挂起。我是否忘记了一些愚蠢的东西(比如空字符或不同的换行符组合)?下面是PHP: socket_connect($sock, $addr, $port); socket_write($sock, 'Hello world'); $str = ''; while($resp = socket_read($

我使用PHP连接到本地C++ socket服务器,以保持Web应用程序和几个守护进程之间的状态。我可以向套接字服务器发送数据,但不能从它接收数据;它只是阻塞
socket\u read()
并无限期挂起。我是否忘记了一些愚蠢的东西(比如空字符或不同的换行符组合)?下面是PHP:

socket_connect($sock, $addr, $port); 
socket_write($sock, 'Hello world');
$str = '';
while($resp = socket_read($sock, 1000))
    $str .= $resp;
socket_close($sock);
die("Server said: {$str}");
套接字服务器的相关部分如下所示(请注意,
运算符过载):

std::字符串数据;
sock>>数据;
sock
调用
Socket::recv(std::string&)
>
调用
Socket::send(const std::string&)


这在(例如)telnet中可以很好地工作,但是PHP不想玩得很好。非常感谢您的任何想法/建议。

我实际上刚刚解决了一个类似的问题,除了管道()。我不知道这个解决方案在多大程度上是相似的,但也许值得一看?我同意你应该在读写之间坚持一个测试,看看是否在C++中挂上了SoCK>数据线,或者在PHP中的SpOK 套接字,就像大多数编程语言一样,默认情况下是在阻塞模式下打开的,除非设置为<代码> SokoStSuxNoBub/<代码> .< 这意味着除非发生超时/错误或接收到数据,
socket\u read
将永远挂在那里

由于您的终止字符似乎是新行,请尝试:

while($resp = socket_read($sock, 1000)) {
   $str .= $resp;
   if (strpos($str, "\n") !== false) break;
}
socket_close($sock);
die("Server said: $str");

TCP套接字通常尝试将多个小型发送调用合并到一个数据包中,以避免发送太多的数据包()。这可能是在send()调用之后无法接收任何内容的原因。您必须使用打开套接字以避免出现这种情况。

您也可以在从套接字读取时尝试以下操作:

if(socket_recv ( $socket , $response , 2048 , MSG_PEEK)!==false)
{
   echo "Server said: $response";
}

注意:使用<强> MSGWAWITALWA/SUGR>代替<强> MSGPEPEK 可能会导致套接字挂起(从我曾经的一次经历)。

C++中使用的是什么套接字库,还是您自己创建了(*NIX还是Windows)?还有,错误是什么?它只是永远阻塞sock>>数据还是发生了更多的事情;我暂时还没有使用与C++服务器的PHP通信,但是服务器是否将一个终止发送到套接字,这样它就告诉PHP停止读取?您的循环将在PHP中持续读取,直到服务器告诉它套接字已完成发送信息;这不是一个实时更新(因为它会在数据完全收集并存储在您的var中之后打印数据)。这可能只是您的代码中缺少的,但是您是不是先创建了
socket
sock?另外,我在您的代码中没有看到这一点,但是在循环完成时您需要打印$str。哎哟,我不小心漏掉了上面更新的代码中的
socket\u create()
。我应该早一点澄清的,对不起,这是尼克斯。本身没有任何错误;服务器本身工作正常(我可以远程登录,并且工作正常)-是PHP的
socket\u read()
无限期挂起。socket服务器只是我临时拼凑的一个服务器,因为我找不到一个好的服务器(任何建议都很好)。事实上,我知道默认情况下它们会阻塞,但我完全忘记了a)在编写响应后关闭socket,或b)中断循环。谢谢你。使用空字符似乎不起作用,如果我切换它,(理想情况下它不会是换行符)-如果我尝试<代码> StruPs($STR,“0”)在代码> SCOPE不同于C或C++,PHP不会在字符串的末尾放置空字节,这就是为什么<代码> SrPoS< <代码> > <代码> \ 0 < /Cord>在测试时产生布尔假。你必须提供另一个分隔符,使用一个超时(请参阅),或者从服务器端关闭套接字。这很公平——通过在我端的测试,我也意识到了这一点。谢谢你的帮助!我认为只搜索$resp:
if(strpos($resp,“\n”)!==false)break可以稍微改进代码
if(socket_recv ( $socket , $response , 2048 , MSG_PEEK)!==false)
{
   echo "Server said: $response";
}