tags:

views:

766

answers:

3

Here is my code:

<?php

$host = "127.0.0.1";
$portListen = 1234;
$portSend = 1240;


// create socket
$sSender = socket_create(AF_INET, SOCK_STREAM, 0);

socket_connect($sSender, $host, $portListen);

socket_write($sSender, "test", strlen ("test"));


$sListen = socket_create(AF_INET, SOCK_STREAM, 0);
socket_set_option($sListen, SOL_SOCKET, SO_REUSEADDR, 1);

socket_bind($sListen, $host, $portSend);

socket_listen($sListen,1);
$dataSock = socket_accept($sListen);
echo socket_read($dataSock, 3, PHP_NORMAL_READ);

// close sockets
socket_close($sSender);
socket_close($sListen);
?>

I send "test" to another application, it receives, and send back "ack". Problem is, I can only do it once. If I refresh, I get the address is already used error. I tried the solutions suggested on php.net but to no avail. Trying to socket_shutdown() before socket_close() only give me not connected warning, and upon refreshing will give me a never ending loading.

From what I understand the reason socket is not immediately closed is because there is still data in the buffer. But as you can see I explicitly state to listen to only 1 connection. Plus I am only sending 3 characters from my application and reading 3 in this script.

What am I doing wrong?

edit: The reason I'm using 2 sockets is because I cannot listen() after write() which give me socket is already connected error. Skipping listen() and going straight for read() after write() give me invalid argument error.

+1  A: 

Why do you need to create 2 sockets for read and write? It looks like an odd design. Client apps usually open a socket connection to the server, then send a request and read the server's response on the same socket. Also, creating a listening socket (iow a server) won't scale past any firewall or NAT gateway.

Answer to yor comment: No need to listen. just read (possibly blocking operation if your server hasn't replied yet).

Serge - appTranslator
I thought that's the correct design. I cannot seem to socket_listen with the first socket... I get: Warning: socket_listen() [function.socket-listen]: unable to listen on socket [0]: A connect request was made on an already connected socket. in C:\wamp\www\sock.php on line 22
SyaZ
+1  A: 

After a connection is closed, the socket enters a linger state so that if (during the close) packets were lost and retransmitted, the response would be a clean acknowledgement instead of RST (reset) indicating no such socket was open. It's part of the TCP specification, you can't make it stop happening.

Listen(1) doesn't mean accept only one connection, it means maintain a queue of up 1 connections waiting for an application to accept() them. So as soon as you accept the first, the socket is ready to listen for more.

Like everybody else, I'm wondering why the odd design, but I assume it's a boiled-down example that presents your problem and doesn't necessarily present your real plan.

Liudvikas Bukys
A: 

I see, after having a few hours sleep and re-analyzing my code and the documentations, I managed to fix everything. You guys are right, 1 socket is indeed enough and the correct way:

<?php

$host = "127.0.0.1";
$portListen = 1234;
$sSender = socket_create(AF_INET, SOCK_STREAM, 0) or die("Could not create socket\n");

socket_connect($sSender, $host, $portListen) or die("Could not connect\n");

socket_write($sSender, "test", strlen ("test")) or die("Could not write output\n");

echo socket_read($sSender, 3, PHP_NORMAL_READ);

socket_close($sSender);
?>

So simple!

SyaZ