Page 1 of 1
Server/Client Sockets with PHP
Posted: Sun Feb 06, 2005 12:17 pm
by NightWalker
I checked the documentation about sockets on php.net, but I haven't been able to set up anithing using sockets...
I'm running Windows XP Pro, Apache 2.0.52, PHP 4.3.10
This is what I've done:
I edited the following in the php.ini file in the Windows folder:
extension_dir = c:/mywebserver/php/extensions
extension=php_sockets.dll
I copyed the php_sockets.dll from php/extensions/ and pasted it inside windows, windows/system/ and windows/system32/ folders.
I'm testing the following code:
Code: Select all
<?php
// Set time limit to indefinite execution
set_time_limit (0);
// Set the ip and port we will listen on
//$address = '192.168.0.100';
$address = 'localhost';
$port = 9000;
// Create a TCP Stream socket
$sock = socket_create(AF_INET, SOCK_STREAM, 0);
// Bind the socket to an address/port
socket_bind($sock, $address, $port) or die('Could not bind to address');
// Start listening for connections
socket_listen($sock);
/* Accept incoming requests and handle them as child processes */
$client = socket_accept($sock);
// Read the input from the client – 1024 bytes
$input = socket_read($client, 1024);
// Strip all white spaces from input
$output = ereg_replace("ї \t\n\r]","",$input).chr(0);
// Display output back to client
socket_write($client, $output);
// Close the client (child) socket
socket_close($client);
// Close the master sockets
socket_close($sock);
?>
but I keep getting this:
Code: Select all
Warning: socket_bind() unable to bind address ї0]
I tryed getting my own IP address and is the same...
If I use an address from other machine in my network It says that is not a valid address in this context... what can i do?
thanks!
feyd | please use the formatting we provide
Posted: Sun Feb 06, 2005 12:24 pm
by timvw
afaik, binding to "0.0.0.0" will bind to all available ip addresses....
binding to "otherhost.in.network.example" is usueless, because that interface is not in your machine...
no experience with the socket extension in php though (i'm someone who thinks there are better languages/environments for applications that listen to a socket......)
Posted: Sun Feb 06, 2005 12:47 pm
by NightWalker
timvw wrote:afaik, binding to "0.0.0.0" will bind to all available ip addresses....
binding to "otherhost.in.network.example" is usueless, because that interface is not in your machine...
no experience with the socket extension in php though (i'm someone who thinks there are better languages/environments for applications that listen to a socket......)
why do I have to bind the address anyway? I did a Server/Client app in C++ Builder and the Server Socket just needs the port it will listen to, and the Client Sockets do need the port and the address of the server, I want to do the same using PHP, but I dont know how, I just have basic tasks experience using PHP...
How am I supposed to respond to events on the socket connection (when a client logs in or out.)?
PHP is a server side script so it wont be dispached to the client browser until it's complete, how the socket will be constantly listening if it has to be dispached for showing anything...?
Posted: Sun Feb 06, 2005 1:46 pm
by timvw
why do I have to bind the address anyway? I did a Server/Client app in C++ Builder and the Server Socket just needs the port it will listen to, and the Client Sockets do need the port and the address of the server, I want to do the same using PHP, but I dont know how, I just have basic tasks experience using PHP...
my educated guess is that if you bind a socket to a port it defaults to all available interfances... From what i've read untill now, PHP seems to have problems with the default/NULL value...
How am I supposed to respond to events on the socket connection (when a client logs in or out.)?
accepting incoming connections is usually done with a while (true) loop...
if socket_recv returns 0 the client has disconnected (rtfm).
PHP is a server side script so it wont be dispached to the client browser until it's complete, how the socket will be constantly listening if it has to be dispached for showing anything...?
i don't have a clue what you are trying to say here.. But how would your code respond if 2 people run that script at the same time? Only one socket can bind to an address/port at the same time.....
Posted: Sun Feb 06, 2005 1:57 pm
by NightWalker
timvw wrote:accepting incoming connections is usually done with a while (true) loop...
if socket_recv returns 0 the client has disconnected (rtfm). .
timvw wrote:i don't have a clue what you are trying to say here.. But how would your code respond if 2 people run that script at the same time? Only one socket can bind to an address/port at the same time....
That is what i meant, if you got to have a infinite loop the PHP script won't end until the loop is done processing, therefore the PHP script will never be dispached to the web browser...
I want to have the PHP Socket Server running on a web page, waiting for clients and when a client conects I have to produce some kind of message on the page the Socket Server is running...
Posted: Mon Feb 07, 2005 12:44 am
by Jerryscript1
Your best bet is to use the CLI version of PHP for a socket server. Using a webpage version would require using something like flock to prevent the same script from being run by multiple calls to the webpage. Once the socket server is running, you can access it with multiple browsers, hence the need for the while loop.
I hate to admit it, but due to the lack of examples/docs on PHP socket servers, you might have better luck using a prebuilt Java or other language server.
Posted: Mon Feb 07, 2005 2:50 am
by timvw
imho, the easiest way to get some working server/daemon with tcp/ip is to look at a project like eggdrop, and strip the main function... this way you can get relatively quick some portable (and tested) code...

Posted: Mon Feb 07, 2005 9:22 am
by NightWalker
What's that CLI thing?
Can't I have the PHP Server script "running" on my browser?
The examples I've seen they seem to do it by having the Server running on a command line window or something like that, but it seems for linux, How is this exactly done? and can it been done on Windows XP?
For example I found this test code:
Code: Select all
<?php
/* Allow the script to hang around waiting for connections. */
set_time_limit(0);
/* Turn on implicit output flushing so we see what we're getting
* as it comes in. */
ob_implicit_flush();
//$address = '192.168.1.53';
$address = 'localhost';
$port = 1024;
if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "<br>socket_create() failed: reason: " . socket_strerror($sock) . "\n";
}
echo "<br>sock = " . $sock;
if (!@socket_setopt($sock,SOL_SOCKET,SO_REUSEADDR,1)) {
echo "socket_setopt() failed: reason: ".socket_strerror(socket_last_error($sock))."\n";
exit;
}
if (($ret = socket_bind($sock, $address, $port)) < 0) {
echo "<br>socket_bind() failed: reason: " . socket_strerror($ret) . "\n";
}
echo "<br>bind = " . $ret . " sock = " . $sock . " address = " . $address . " port = " . $port;
if (($ret = socket_listen($sock, 5)) < 0) {
echo "socket_listen() failed: reason: " . socket_strerror($ret) . "\n";
}
echo "<br>listen = " . $ret . " sock = " . $sock;
/* Accept incoming requests and handle them as child processes */
$client = socket_accept($sock);
// Read the input from the client – 1024 bytes
//$input = socket_read($client, 1024);
// Strip all white spaces from input
//$output = ereg_replace("ї \t\n\r]","",$input).chr(0);
// Display output back to client
//socket_write($client, $output);
// Close the client (child) socket
//socket_close($client);
/*do {
*/
/* if (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
break;
}
/* Send instructions. */
/* $msg = "\nWelcome to the PHP Test Server. \n" .
"To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
socket_write($msgsock, $msg, strlen($msg));
do {
if (false === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
echo "socket_read() failed: reason: " . socket_strerror($ret) . "\n";
break 2;
}
if (!$buf = trim($buf)) {
continue;
}
if ($buf == 'quit') {
break;
}
if ($buf == 'shutdown') {
socket_close($msgsock);
break 2;
}
$talkback = "PHP: You said '$buf'.\n";
socket_write($msgsock, $talkback, strlen($talkback));
echo "$buf\n";
} while (true);
socket_close($msgsock);
} while (true);
*/
socket_close($sock);
?>
I found several places with scripts that say that:
before you try to execute the script, make sure you have the right permissions on it:
chmod 755 myfile.php
Also make sure that the first line (#!/usr/local/bin/php -q) of the script points at your PHP binary. Then, start the server:
./myfile.php
Those are linux command line instructions, right? Can I test that script on Windows XP using my browser? how?
When I try the code above with the socket_accept line on, my browser just loads the page forever.. this is because it is waiting fo a client to connect, right?
why do I have to put this
Code: Select all
if (!@socket_setopt($sock,SOL_SOCKET,SO_REUSEADDR,1)) {
echo "socket_setopt() failed: reason: ".socket_strerror(socket_last_error($sock))."\n";
exit;
}
before the socket_bind(), otherwise it tells me that the port is already on use...?
Posted: Mon Feb 07, 2005 6:57 pm
by Jerryscript1
CLI=command line interface
When you install PHP on windows, there are several executables, one of which is used from the command line (windows->run)
The browser interface can be used, but will appear to "run forever" unless written to give you a interactive browser interface (which I haven't seen an example of posted anywhere).
The permissions issue is for Linux, and the shebang line is for a cgi version rather than a built in module of PHP.
Running a socket server on Windows can be dangerous, and needs to be designed with security in mind.