代码之家  ›  专栏  ›  技术社区  ›  mway

无法从套接字读取(挂起)

  •  7
  • mway  · 技术社区  · 14 年前

    编辑:对不起,不小心贴出了另一个问题的标题。固定的。

    我使用PHP连接到本地C++套接字服务器,以保持Web应用程序和几个守护进程之间的状态。我可以向socket服务器发送数据,但不能从它接收数据;它只会阻塞 socket_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}");
    

    socket服务器的相关部分如下(注意 << >>

    std::string data;
    sock >> data;
    sock << data << std::endl;
    

    在哪里? >> Socket::recv(std::string&) >> 电话 Socket::send(const std::string&) .

    4 回复  |  直到 14 年前
        1
  •  11
  •   netcoder    11 年前

    与大多数编程语言一样,PHP中的套接字默认以阻塞模式打开,除非使用 socket_set_nonblock

    这意味着除非发生超时/错误或接收到数据, socket_read 会永远挂在那里。

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

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

    TCP套接字通常尝试将多个小的发送调用合并到一个数据包中,以避免发送过多的数据包( Nagle's algorithm ). 这可能是send()调用后无法接收任何内容的原因。你必须打开插座 TCP_NODELAY

        3
  •  0
  •   Community Navdeep Singh    7 年前

    实际上我刚解决了一个类似的问题,除了管道( Is php's fopen incompatible with the POSIX open for pipes ). 我不知道这个解决方案在多大程度上是相似的,但也许值得一看?我同意激烈的说法,你应该坚持读写线之间的一个测试,看看C++是否挂在袜子& GT;数据线或袜子& lt;和数据线…

        4
  •  0
  •   Jimmy Ilenloa    11 年前

    从套接字读取时,也可以尝试此操作:

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

    注:使用 代替 味千 可能会导致socket挂起(根据我曾经的一次经验)。