I’m facing a weird issue.
I wrote a small server in C++ that stores object in a binary format in a file.
I tested it succesfully with 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
The output on the server is now
Command : store 1 1 5 1
Command : store 1 1 5 2
Since we are going to use php to store those info I wrote a small php script that would send 10 commands to our server.
<?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);
?>
The problem is that the output from the server is now:
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
The \r\n is not recognized. After searching around I found that by adding a usleep(10000) after the socket_write function it would actually work.
I’m trying to avoid using this workaround, so I have to questions :
Why does usleep fixes it ?
How can I do it without usleep ?
Thanks for reading!
We would have to see your C++ server for sure, but I suspect you are parsing the data incorrectly there.
TCP is a stream protocol, and in the protocol there are no boundaries to the data in the packets. So when you send multiple “store” commands, they might all appear in the same TCP packet. Then when you call
recv()you may get multiple “store”. However, due to timing, and the fact that telnet might be sending each line in it’s own packet, each call torecv()might retrieve a single “store” command.When you put the usleep in, you are effectively delaying queuing up more data, and TCP gives up waiting and sends the “store” in a packet all on it’s own.
In your server you have to
recv(),recv()calls.The
usleepis a hack, that might not always work.