Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't read from socket (hangs)

Tags:

c++

php

sockets

I am using PHP to connect to a local C++ socket server to keep state between a web app and a couple of daemons. I can send data to the socket server, but not receive from it; it just blocks on socket_read() and hangs indefinitely. Am I forgetting something dumb (like a NULL character or a different combination of newline characters)? The PHP is below:

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}");

The related part of the socket server is below (note that the << and >> operators are overloaded):

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

Where >> calls Socket::recv(std::string&) and >> calls Socket::send(const std::string&).

This works fine from (for example) telnet, but PHP doesn't want to play nice. Any thoughts/suggestions are appreciated.

like image 936
mway Avatar asked Nov 09 '10 19:11

mway


2 Answers

Sockets in PHP, as in most programming languages, are opened in blocking mode by default, unless set otherwise using socket_set_nonblock.

This means that unless a timeout/error occurs or data is received, socket_read will hang there forever.

Since your termination character seems to be a new line, try that:

while($resp = socket_read($sock, 1000)) {
   $str .= $resp;
   if (strpos($str, "\n") !== false) break;
}
socket_close($sock);
die("Server said: $str");
like image 85
netcoder Avatar answered Sep 25 '22 02:09

netcoder


TCP sockets usually try to combine multiple small send calls into one packet to avoid sending too many packets (Nagle's algorithm). This may be the cause that you can't receive anything after the send() call. You will have to open the socket with TCP_NODELAY to avoid that.

like image 36
lothar Avatar answered Sep 21 '22 02:09

lothar