l008com Posted December 29, 2014 Share Posted December 29, 2014 (edited) 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); Edited December 29, 2014 by l008com Quote Link to comment Share on other sites More sharing options...
kicken Posted December 29, 2014 Share Posted December 29, 2014 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); Quote Link to comment Share on other sites More sharing options...
l008com Posted December 31, 2014 Author Share Posted December 31, 2014 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); Quote Link to comment Share on other sites More sharing options...
l008com Posted December 31, 2014 Author Share Posted December 31, 2014 (edited) 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? Edited December 31, 2014 by l008com Quote Link to comment Share on other sites More sharing options...
l008com Posted December 31, 2014 Author Share Posted December 31, 2014 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" )); Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.