homepage Welcome to WebmasterWorld Guest from 23.22.29.137
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
Forum Library, Charter, Moderators: coopster & jatar k

PHP Server Side Scripting Forum

    
Playing With Sockets With PHP
l008comm




msg:4623192
 9:02 am on Nov 14, 2013 (gmt 0)

I'm trying to whip up some PHP that will open a TCP socket connection to a specified port on a specified host. That's all I'm doing is opening the connection, then closing it. I'm essentially just sniffing ports so I don't need to send or receive any data. I know of two ways to do this:
  1. fsockopen()
  2. socket_create(), socket_connect()


But as with all things in life, things get hung up in the details. There are two very important 'features' that I need.

First, I need to be able to bind this outgoing connection to alternate IP that my server has. This website is running on it's own unique IP, and this IP is not the server's default IP. So I'd like all outgoing connections from this site to also use this unique IP. As it turns out, you can bind to an IP using socket_bind() with the socket_create() function. It works nice and easy.

Second, I need to set a connection timeout. Not a read/write timeout, because I'm not actually reading or writing anything. I'm just opening the connection, and then closing it. So I need a way to apply a timeout to that process. As it turns out, fsockopen() supports connection timeouts by default, just stick an int as the 5th argument when calling the function. Nice and easy.

But the problem is that (as far as I've been able to learn), you can't bind to an IP with fsockopen() and you can't set a connection timeout with socket_create()/socket_connect(). Here is the code I have. I tried both techniques, but each one has it's corresponding flaw as mentioned above. using socket_create(), i've even tried setting the default_socket_timeout ini value using ini_set() but nothing seems to have any effect.

I've also read somewhere that I could possibly make socket_connect() connect using a non blocking connection. Which would not hold up the script while the connection is attempted. This why, I could simply give up waiting for a result after my $timeout. The problem is, other than casual mentions, I haven't been able to find any documentation or sample code of how you'd actually DO this. I don't know if it would even work.

So here is my original code, using fsockopen(). It has a connection timeout and it works great, except that the connections are coming from the wrong IP address because I haven't found any way to bind these connections to another IP address.

<?php
$sock = @fsockopen($ip,$port,$errno,$errstr,$timeout);

if ($sock)
{
// Open
fclose($sock);
return 1;
}
else
{
if ($errno === 60)
{
// Timeout
return 2;
}
else 
{
// Closed
return 3;
}
}

?>

Here was my second try using socket_create() and socket_connect(). These connections are bound to the proper IP address, but there is no way to set a connection timeout. This means that if the port is blocked by a firewall, my PHP script will keep running for about 45 seconds until it gives up. In this code, I even tried setting the read and write timeouts to see if that would work, but it does not. Nor does setting the default_socket_timeout value.

<?php
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);

if ( $sock_status )
{
// Open
socket_close($sock);
return 1;
}
else
{
$sock_error = socket_last_error($sock);

if ($sock_error === 61)
{
// Closed
return 3;
}
else
{
// Timeout
return 2;
}
}

?>

Anyway, this is my dilemma. I'm sure there must be some way to make this work, but it seems like PHP socket functions just aren't used that much, and because of that, they don't have nearly as much documentation and sample code across the internet.

[edited by: phranque at 11:35 pm (utc) on Dec 26, 2013]
[edit reason] syntax=php [/edit]

 

coopster




msg:4633669
 5:09 pm on Dec 26, 2013 (gmt 0)

I looked at this for a bit today and couldn't come up with a quick answer either, l008comm. Have you considered cURL instead maybe?

brotherhood of LAN




msg:4633692
 7:32 pm on Dec 26, 2013 (gmt 0)

cURL does allow you to choose the network interface and it's quite easy to use.

curl_setopt($handle,CURLOPT_INTERFACE,$interface_or_ip_to_use);

l008comm




msg:4633740
 11:15 pm on Dec 26, 2013 (gmt 0)

Everyone suggests this on every forum I've posted this on. But I'm not downloading anything, I'm opening a connection on a tcp port, then closing it. Can you really ports can like that with curl? I don't think so?

phranque




msg:4633742
 11:38 pm on Dec 26, 2013 (gmt 0)

seems like socket_set_option should have done the job.
i would add proper error checking everywhere and try socket_set_option before socket_bind as in the example.

PHP: socket_set_option - Manual:
http://www.php.net/manual/en/function.socket-set-option.php [php.net]

also, i'm not a php expert, but "@socket_connect"?

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / PHP Server Side Scripting
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved