Page 1 of 1

sockets

Posted: Thu Jan 12, 2006 3:26 am
by s.dot
please excuse my newbness here but I'm delving into a new area of php and i don't really know what to do/expect. I've read a couple tutorials on sockets, and found a pretty good one. I copy/pasted a socket script that listens for connections and accepts them.. and I want to play around with it. however, i don't exactly know what I'm playing around with!

When I run the script in my browser, it just shows a blank page... forever. Which is good I think because it means that its made the socket and its listening for connections.

But now I don't know what to do. Should this be ran through command line instead? Err I don't really know what to ask! Can someone just point me in the right direction on how to start using/editing this tutorial: Where would the $input be coming from?

Code: Select all

<?php
set_time_limit (0);

$address = '192.168.1.2';
$port = 9000;
$max_clients = 10;

$clients = Array();

// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);

socket_bind($sock, $address, $port) or die('Could not bind to address');


// Start listening for connections
socket_listen($sock);

// Loop continuously
while (true) {
	
	// Setup clients listen socket for reading
	$read[0] = $sock;
	
	for ($i = 0; $i < $max_clients; $i++)
	{
		if ($client[$i]['sock']  != null)
			$read[$i + 1] = $client[$i]['sock'] ;
	}
	
	
	// Set up a blocking call to socket_select()
	$ready = socket_select($read,$null=null,$null=null,$null=null);
	
	
	/* if a new connection is being made add it to the client array */
	if (in_array($sock, $read)) {
		for ($i = 0; $i < $max_clients; $i++)
		{
			if ($client[$i]['sock'] == null) {
				$client[$i]['sock'] = socket_accept($sock);
				break;
			}
			elseif ($i == $max_clients - 1)
				print ("too many clients");
		}
		
		if (--$ready <= 0)
			continue;
			
	}

	// If a client is trying to write - handle it now
	for ($i = 0; $i < $max_clients; $i++) // for each client
	{
		if (in_array($client[$i]['sock'] , $read))
		{
			$input = socket_read($client[$i]['sock'] , 1024);
			if ($input == null) {
				// Zero length string meaning disconnected
				unset($client[$i]);
			}
			$n = trim($input);
			if ($input == 'exit') {
				// requested disconnect
				socket_close($client[$i]['sock']);
			} elseif ($input) {
				// strip white spaces and write back to user
				$output = ereg_replace("[ \t\n\r]","",$input).chr(0);
				socket_write($client[$i]['sock'],$output);
			}
		} else {
			// Close the socket
			socket_close($client[$i]['sock']);
			unset($client[$i]);
		}
	}
}

// Close the master sockets
socket_close($sock);
?>

Posted: Thu Jan 12, 2006 3:51 am
by s.dot
maybe an important note should be that when I run netstat -a at the command prompt, i see something on port 9000 (what i set the script to) that says LISTENING beside it. So I suppose that is my socket listening for connections? what to do with it? ;d

Posted: Thu Jan 12, 2006 5:04 am
by Weirdan
connect to it :)

Code: Select all

c:\>telnet 192.168.1.2 9000
test to see if it strips whitespace
testtoseeifitstripswhitespace
exit
c:>

Posted: Thu Jan 12, 2006 7:33 am
by s.dot
Aye, I think I'm understanding the concept now.

The socket script above creates the socket and runs it to listen for connections to it.
- What do I use to execute this script? Using the browser feels kinda... weird.
- I'm new to the command line stuff but I tried something like C:\php\php.exe C:\path\to\script... with no luck

By telneting to it when it's running we're connecting to it and can use it. Now, scripts can be made to work on this socket rather than telnetting.

Someone correct me if I'm wrong.

( talking through things (even if its to myself) helps me out a lot :) )

Posted: Sat Jun 17, 2006 12:52 pm
by s.dot
Hi guys, I thought I'd ressurect this old topic, because I'm coming back to learning it. I am still using the above script for my socket server. I found it as a tutorial on zend -- and it didn't even work. =/ I made some changes to it and got it working, but I'm not experienced enough in this area to fix the notices and warnings the script is producing.

When i just run the socket server, I don't get any errors. But after connecting to it through telnet, it goes crazy. Here's a short sample of some of the errors I'm getting.

Code: Select all

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined variable: client in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 40

Notice: Undefined offset: 1 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 2 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 3 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 4 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 5 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 6 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 7 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 8 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 9 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 1 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 1 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 2 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 2 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 3 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 3 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 4 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 4 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 5 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 5 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 6 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 6 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 7 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 7 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 8 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 8 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 9 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 56

Notice: Undefined offset: 9 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Warning: socket_close() expects parameter 1 to be resource, null given in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 74

Notice: Undefined offset: 1 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 2 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 3 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27

Notice: Undefined offset: 4 in C:\Program Files\Apache Group\Apache2\htdocs\www\makems\socket_test.php on line 27
How can I fix these errors, so that I can get the simple socket server working correctly, and then begin my process of dismantling it and putting it back together so I can understand how it works :P

Posted: Sat Jun 17, 2006 12:59 pm
by Christopher
All of those are just warnings and notices about undefined variables (perhaps just one). Check like 27, 40, 56 and 74. It looks like the var is parameter one in your call to socket_close(). You should probably do and isset() check on the offending vars before using them.

Posted: Sat Jun 17, 2006 1:07 pm
by printf
The script uses $client as the client(s) array container, but you have $clients = Array ();, change it to $client = array (); Also your using socket_read(), I would change it to socket_recv ()! All the other errors are the result of the first error (no defined array call $client)

pif!

Posted: Sat Jun 17, 2006 1:20 pm
by s.dot
You guys are correct.
The author of this script liked to use if($var == null) and if($var != null) instead of if(isset($var)) and if(!isset($var))
Thanks.

Posted: Sat Jun 17, 2006 2:57 pm
by s.dot
Alright, I've managed to get rid of all of the errors.. thanks to some php.net reading =]

Here's the revised code (working, sort of)

Code: Select all

<?php
set_time_limit (0);


//create our TCP stream socket
$address = '192.168.1.2';
$port = 9000;
$max_clients = 10;

$sock = socket_create(AF_INET, SOCK_STREAM, 0);
socket_bind($sock, $address, $port) or die('Could not bind to address');

//$client container
$client = array();

//listen for connections
socket_listen($sock);

//infinite loop
while(TRUE){
	
	// Setup clients listen socket for reading
	$read[0] = $sock;
	
	for ($i=0;$i<$max_clients;$i++){
		
		if (isset($client[$i]['sock'])){
			
			$read[$i + 1] = $client[$i]['sock'];
			
		}
		
	}
	
	
	//Set up a blocking call to socket_select()
	$ready = socket_select($read,$null=null,$null=null,$null=null);
	
	
	//if a new connection is being made add it to the client array
	if (in_array($sock, $read)){
		
		for ($i = 0; $i < $max_clients; $i++){
			
			if (!isset($client[$i]['sock'])){
				
				$client[$i]['sock'] = socket_accept($sock);
				break;
				
			}
			
			elseif ($i == $max_clients - 1)
				print ("too many clients");
				
		}
		
		if (--$ready <= 0)
		
			continue;
			
	}

	// If a client is trying to write - handle it now
	for ($i = 0; $i < $max_clients; $i++){
		
		if(isset($client[$i]['sock'])){
			
			if(in_array($client[$i]['sock'] , $read)){
				
				$input = socket_read($client[$i]['sock'] , 1024, PHP_BINARY_READ);
				
				if ($input == null) {
				
					// Zero length string meaning disconnected
					unset($client[$i]);
				
				}
				
				$n = trim($input);
				
				if ($input == 'exit'){
					
					// requested disconnect
					socket_close($client[$i]['sock']);
					
				} elseif ($input) {
					
					// strip white spaces and write back to user
					$output = ereg_replace("[ \t\n\r]","",$input).chr(0);
					socket_write($client[$i]['sock'],$output,strlen($output));
					
				}
				
			} else {
				
				// Close the socket
				socket_close($client[$i]['sock']);
				unset($client[$i]);
				
			}
			
		}
		
	}
	
}

// Close the master sockets
socket_close($sock);
?>
What this is supposed to do is remove whitespace and return the output. But when I telnet to it, my input comes out like this:

Code: Select all

teesstt
tthhiiss iiss jjuusstt aa tteesstt ttoo sseeee iiff tthhiiss rreemmoovveess wwhh
iitteessppaaccee

aappppaarreennttllyy iitt ddooeessnn''tt..  iitt''ss jjuusstt eecchhooiinngg eev
veerryy cchhaarraacctteerr tthhaatt II ttyyppee..

hhmmmm..

eexxiitt;;

nnooppee..
The original script had this

Code: Select all

socket_write($client[$i]['sock'],$output);
After looking at php.net examples, I think it should be

Code: Select all

socket_write($client[$i]['sock'],$output,strlen($output));
Although this doesn't seem to affect the output. Seems my input is limited to one character, instead of when \n is reached.