2011-11-25 90 views
0

我正面临一个奇怪的问题。使用PHP作为C++服务器的套接字客户端

我写了一个C++中的小型服务器,它以二进制格式将对象存储在一个文件中。

我用telnet成功测试过它。

telnet 127.0.0.1 1234 
Trying 127.0.0.1... 
Connected to 127.0.0.1. 
Escape character is '^]'. 
store 1 1 5 1 
store 1 1 5 2 

服务器上的输出是现在

Command : store 1 1 5 1 
Command : store 1 1 5 2 

因为我们要使用PHP来存储这些信息,我写了一个小PHP脚本,将派遣10个命令到我们的服务器。

<?php 

    $socket = socket_create(AF_INET,SOCK_STREAM,0); 
    socket_connect($socket,"127.0.0.1",1234); 

    for($i = 0;$i < 10;$i++){ 

     $command = "store 1 $i 5 1\r\n"; 

     echo $command; 

     socket_write($socket,$command,strlen($command)); 

    } 

    socket_close($socket); 

?> 

的问题是,来自服务器的输出是现在:

Command : store 1 0 5 1store 1 1 5 1store 1 2 5 1store 1 3 5 1store 1 4 5 1store 1 5 5 1store 1 6 5 1store 1 7 5 1store 1 8 5 1store 1 9 5 1 

的\ r \ n不认可。在四处搜寻后,我发现通过在socket_write函数后添加一个usleep(10000),它实际上可以工作。

我试图避免使用此解决方案,所以我要提问:

为什么usleep修复它? 如何在不休眠的情况下做到这一点?

感谢您的阅读!

回答

0

我们将不得不看你的C++服务器,但我怀疑你是在那里错误地解析数据。

TCP是一种流协议,在协议中,数据包中的数据没有边界。所以当你发送多个“存储”命令时,它们可能都出现在同一个TCP数据包中。那么当你拨打recv()时,你可能会得到多个“商店”。但是,由于时间安排以及telnet可能将每行发送到自己的数据包这一事实,每个拨打recv()的电话都可能检索到单个“存储”命令。

当你把usleep放入时,你实际上是在延迟排队更多的数据,而TCP放弃了等待,并且把数据包中的“存储”全部发送到它自己的地方。

在你的服务器,你必须

  1. 期待从recv()检索多个“商店” S,
  2. 期待一个单一的“店”在多个recv()电话进行分割。

usleep是一个黑客,可能并不总是工作。

相关问题