Jump to content

Archived

This topic is now archived and is closed to further replies.

l008com

Working With Sockets

Recommended Posts

I'm having issues working with sockets in PHP, I'm hoping someone can help.

 

I'm making an application in which I need to open my own socket connections. There are two specific features that I need:

I need to set a timeout for the connection attempt.

I need these connections to come from a custom IP address, and by that I mean that my server has more than one IP, and I need the socket connection to use an IP that is not the server's default internet connection port.

 

There are (as far as I know) two ways to open a socket connection. Both techniques meet a requirement and miss a requirement.

 

Option 1: I can use the function fsockopen( ) to open the connection. This function works great and let's me set a timeout for the connection itself. It's solid and reliable. However it has, as far as I can tell, no way to set the connection to come from a custom IP. All connections using this function come from the server's default IP address.

 

Option 2: The socket_create( ) / socket_connect( ) family of functions. These functions have a lot more options, they let you do a lot more. I can easily bind the socket to my server's secondary IP address so socket connections will come from it. HOWEVER as far as I can tell, these family of functions lack a connection timeout. You can set timeout for reads and timeouts for writes. But there doesn't seem to be a way to set a timeout for initiating the connection itself. Even setting the "default_socket_timeout" parameter doesn't have any effect on the connection time. 

 

This type of question is a bit more technical than most PHP questions. But I'm hoping someone out there knows a way I can open sockets while meeting both of my two requirements. It's entirely possible that it is not possible, I know. But hopefully it can be done.

 

One thought I had was a way of using the second option, and wrapping the whole socket_connect( ) function inside of another function that sets a timeout, and would kill the socket_connect( ) function once the timeout was met. However, I don't know of any such system in PHP, this was only a concept theory. 

 

 

How I open my sockets using fsockopen( ):

$sock = @fsockopen($ip,$port,$errno,$errstr,$timeout);
 
How I open my sockets using socket_create( ):
ini_set("default_socket_timeout",$timeout);
$sock = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_bind($sock,OPERATING_IP);
socket_set_option($sock, SOL_SOCKET, SO_RCVTIMEO, array("sec" => $timeout, "usec" => 0));
socket_set_option($sock, SOL_SOCKET, SO_SNDTIMEO, array("sec" => $timeout, "usec" => 0));
$sock_status = @socket_connect($sock,$ip,$port);

Share this post


Link to post
Share on other sites

There are (as far as I know) two ways to open a socket connection. Both techniques meet a requirement and miss a requirement.

Option 3) stream_socket_client

 

The bind address can be set using the context parameter. Create a context and set it's bindto option to the IP you want.

 

$timeout = '5';
$params = array('socket' => array('bindto' => 'x.x.x.x'));
$context = stream_context_create($params);
$socket = stream_socket_client('tcp://remote.host:port', $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);

Share this post


Link to post
Share on other sites

So I got around to playing with this tonight. This new way of opening sockets does work. And the timeout does seem to work properly (although I do need to do some more thorough testing, but so far so good. 

 

HOWEVER it does not appear to be binding to the IP provided.

 

This is what I have going on:

 

$params = array('socket' => array('bindto' => OPERATING_IP));
$context = stream_context_create($params);
$socket = @stream_socket_client("tcp://$ip:$port", $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);

Share this post


Link to post
Share on other sites

Wow this forum loves to eat half my post spontaneously. The REST of the post above said that OPERATING_IP is a user defined constant but it still doesn't work even if I hard code the IP address in there as a string.

 

And yes I verified the IP is correct.

 

And I also verified again that the socket_create( ) / socket_bind( ) code from above, DOES bind to the proper IP. This is the code that works but has no connection timeout. 

 

So any thoughts on why binding with stream_socket isn't working?

Share this post


Link to post
Share on other sites

So turns out the bindto IP needs to be in the format of x.x.x.x:0, so I changed my code a bit and now it's working properly:

 

$options = array("socket" => array("bindto" => OPERATING_IP.":0" ));

Share this post


Link to post
Share on other sites

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.