Socket Bind Error when running script from another PC

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
ckli6
Forum Newbie
Posts: 3
Joined: Sat Sep 30, 2006 12:45 am

Socket Bind Error when running script from another PC

Post by ckli6 »

Hi,

I have a form with 2 buttons, namely, Listen and Send, Send is for sending a Message to the remote host at the Port specified by the form, Listen is simply Creating a Socket, bind the port and listen for 3 seconds, if a message has been received, it will display the message on the HTML form. The protocol I am using is UDP.

I am testing this on an intranet with 2 PC's running XP, on my Server, I am using PHP 5.1 and IIS.

This is how I tested my script:

On the Server, run the script and 'Listen', on the other PC (client), run the script and Send a message to the Server, the script works fine and was able to display the incoming message properly.

However, if I start the script on the Client PC (ie not the one with PHP & IIS installed), when I press the Listen button, it will fail with the following message:

socket_bind: unable to bind address[0]:The requested address is not valid in its context.

Any ideas what's causing this.... below is the PHP Code that I'm using:

Code: Select all

<?php
   $host = $_SERVER['REMOTE_ADDR'];
   $post = 1001;
   set_time_limit(0);
   $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP) or die("Could not create socket\n");
 

   switch ($_POST['socktest']) {
     case 'Listen': {
       $buffer=' ';
       echo '<div id="mainbody"><p>Listening....</p></div>';
       echo '<div id="mainbody"><p>Received connection request.</p></div>';
       $result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
       socket_set_nonblock($socket) or die("Could not set non blocking mode.");
       $cont_flag = TRUE;
       $timeout = time() + ($wait_time); // 3 seconds timeout
         while ((time() <= $timeout) && $cont_flag) {
             @socket_recv($socket, $buffer, 100,  2); 
             if (@socket_recv($socket, $buffer, 100,  2)) {
               echo '<div id="mainbody"><p>Received Data from IP ' . $host .  ' : ' . $buffer .  ' </p></div>';
               echo '<div id="mainbody"><p>Total Bytes Received Data from IP ' . $host .  ' : ' . strlen($buffer) .  ' </p></div>';
               $in_msg = $host . ':' . $buffer ;
               $buffer = '';
               $cont_flag = FALSE;
             } else {
                continue;
             }
         } 
       echo '<div id="mainbody"><p>Closing sockets</p></div>' ;
       // close sockets
       socket_close($socket);
       break;
     }
     case 'Send': {
       socket_sendto($socket, $msg, strlen($msg), 0, $remote_host, $port);
       socket_close($socket);
       break;
     }
   }
?>
Thanks in advance!

Regards,
CK
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

$result = socket_bind($socket, $host, $port) or die("Could not bind to socket\n");
Where do $host and $port come from?
Maybe like $_POST['socktest'] they are form data and stored in $_POST.
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Post by Mordred »

1. $port = 1001;


2. $cont_flag = FALSE; is called "break" :)

3. While loop with no sleeping is a CPU hog. The correct way is to use

Code: Select all

socket_select()
4. Wouldn't calling socket_recv twice lose the first buffer?
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

I thought the socket functions only existed in CLI. Interesting :)
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Post by Weirdan »

Obviously you should pass the ip of the local interface to socket_bind(), not the $_SERVER['REMOTE_ADDR'].
User avatar
n00b Saibot
DevNet Resident
Posts: 1452
Joined: Fri Dec 24, 2004 2:59 am
Location: Lucknow, UP, India
Contact:

Post by n00b Saibot »

also $remote_host is not defined anywhere

Code: Select all

socket_sendto($socket, $msg, strlen($msg), 0, $remote_host, $port);
ckli6
Forum Newbie
Posts: 3
Joined: Sat Sep 30, 2006 12:45 am

Post by ckli6 »

Hi,

Thank you all for all the suggestions and pointers.

Actually, this script is embedded in an HTML form.
So these values are actually coming from the form: $port, $wait_time, $host (which will return the local pc's ip) and $remote_host.

One thing is: I've tried adding usleep(100000) in my while loop, but still the cpu utilization is 100% for the entire duration when it tries to read from the port.

I will try to using 'socket_select' and see how it goes.

But there is one thing I'm not sure and it's not clearly stated in the manual, before I use the socket_select function, do I need to bind the socket first? Or, the socket_select function will handle the bind automatically? Of course, I asssume the sockets must be declared first using socket_create befor issuing the socket_select.

Any ideas?

Thanks!

Regards,
CK
User avatar
volka
DevNet Evangelist
Posts: 8391
Joined: Tue May 07, 2002 9:48 am
Location: Berlin, ger

Post by volka »

ckli6 wrote:So these values are actually coming from the form: $port, $wait_time, $host (which will return the local pc's ip) and $remote_host.
That's only true for old versions of php or if register_globals is on (since php 4.2 it defaults to off)
see http://de2.php.net/security.globals
User avatar
Mordred
DevNet Resident
Posts: 1579
Joined: Sun Sep 03, 2006 5:19 am
Location: Sofia, Bulgaria

Post by Mordred »

bind() first.

create(), bind(), set_nonblock(), select() -> recvfrom()/sendto(). Oh yeah, don't use recv(), use recvfrom(), that's the right way of getting the remote sender, what you are doing currently is only correct if both scripts are on the same server.
ckli6
Forum Newbie
Posts: 3
Joined: Sat Sep 30, 2006 12:45 am

Post by ckli6 »

Mordred wrote:bind() first.

create(), bind(), set_nonblock(), select() -> recvfrom()/sendto(). Oh yeah, don't use recv(), use recvfrom(), that's the right way of getting the remote sender, what you are doing currently is only correct if both scripts are on the same server.
Thank you, Mordred.

I'll take your approach and give it a shot... will report back later...

Regards,
CK
Post Reply