Hudzilla.org - the homepage of Paul Hudson
Contents > Networks > Sockets Wish List | Report Bug | About Me ]

15.1.4     Sockets can be servers: socket_create_listen(), socket_accept(), socket_write(), socket_read(), and socket_close()

This is NOT the latest copy of this book; click here for the latest version.

resource socket_create_listen ( int port [, int backlog])

resource socket_accept ( resource socket)

int socket_write ( resource socket, int length [, int length])

string socket_read ( resource socket, int length [, int type])

void socket_close ( resource socket)

We have just covered the basic use of sockets in PHP, and the next step is to move onto the advanced, more flexible sockets that allow you to create more advanced networking scripts with PHP.

There are several functions of interest here: socket_create_listen(), socket_accept(), socket_write(), socket_read(), and socket_close(). In order, those functions create and instruct a socket to listen on a given port, receive a client connecting to the socket, write text out to the client, read text sent by the client, and close the socket.

The sockets system starts with socket_create_listen(), which takes a port number to listen on as its only parameter. This function creates a socket, binds it to the port you specify, and returns a pointer to the socket it created or false if it failed. You will need the socket resource it returns for later functions, so you should always save it in a variable. If the function fails, it is likely because the port you specified is already being used, or perhaps because you have insufficient privileges to open the port.

The socket_accept() function takes the return value of socket_create_listen() as it is only parameters, and returns a client connection - someone who connected to our port number. Socket_accept() works by examining the queue of people waiting to be served, and taking the first client from there - if there are no clients waiting to be served, socket_accept() will wait ("block") until a client does become available, at which point it will return that.

Socket_write() takes two parameters, which are the client to write to and the value you want to write - this data is then sent through our socket to the client, as you would expect. Its partner, socket_read(), also takes two parameters, which are the connection to read from, and the number of bytes to read. By using socket_write() and socket_read() together, you can fully interact with clients connecting to your socket.

Here is an example script that creates a ROT13 server - when people connect to it and send text, it responds with the ROT13 equivalent of their text.

<?php
    $socket
= @socket_create_listen("12345");

    if (!
$socket) {
        print
"Failed to create socket!\n";
        exit;
    }

    while (
true) {
        
$client = socket_accept($socket);
        
$welcome = "\nWelcome to the Amazing ROT13 Machine.\nType '!close' to close this connection, or type '!halt' to halt the server.\n";
        
socket_write($client, $welcome);

        while (
true) {
            
$input = trim(socket_read ($client, 256));
            if (
$input == '!close') {
                break;
            }

            if (
$input == '!halt') {
                
socket_close ($client);
                break
2;
            }

            
$output = str_rot13($input) . "\n";
            
socket_write($client, $output);
            print
"Them: $input, Us: $output\n";
        }

        
socket_close ($client);
    }

    
socket_close ($socket);
?>

Because this is going to serve data over a potentially infinite length of time, it is important you execute that script using the CLI SAPI, not your web browser. Once you have it running, bring up a new command-line window and enter the following:

telnet localhost 12345

That should launch your telnet program, which is useful for forming simple connections to servers. All being well, you should receive the welcome message from the ROT13 server - try it out with a few words, then type !shutdown to finish. If you have followed correctly so far, you should see something like the picture below.







<< 15.1.3 Sockets aren\'t all about HTTP   15.1.5 Sockets can be powerful >>
Table of Contents
Want to see this stuff in print? PHP in a Nutshell takes the core topics covered here, adds in thousands of edits from the editorial team and myself, and combines them to make an unbeatable reference for PHP programmers at all levels.



My latest book has hundreds more tips on how to use PHP, Apache, and MySQL, plus Perl, Python, shell scripts, performance tuning, and more!



Top-right shadow
 
Bottom-left shadow Bottom shadow

Comments from other readers
Kamal Hossain - 20 Aug 2008

Would u plz tell me how to control multi user. Because server is wait at socket_accept() funtion thus i m not able to implement this in loop. is there any way....

pallav_vns@yahoo.co.in - 20 Aug 2008

how to run the script to create ROT13 server, i dont have CLI SAPI

A PHP User - 20 Aug 2008

In Windows, add PHP_NORMAL_READ as the last parameter to socket_read(). As in, socket_read($client, 256, PHP_NORMAL_READ);

A PHP User - 20 Aug 2008

Okay...now it's only letting me input ONE char...

A PHP User - 20 Aug 2008

It won't give me a response until I type 256 characters...

A PHP User - 20 Aug 2008

Is this server multi-threaded?

A PHP User - 20 Aug 2008

If I run this script on my computer and use telnet, the program won't let me input more than one character. It just shows the result as soon as I input the first character
What should I do?



Add comment
Please note that by posting a comment here you are committing it to the public domain. This is important so that others can make use of your code themselves, and also so that I can incorporate helpful notes directly into the main text. Comments are limited to 2000 characters in length.

If you are reporting an error in the content, please tell me directly.

Your name/email address:
Your comment:
 
Now, in order to verify that you're a real person, please answer this simple question: what is three plus seven?
The answer is:
(please write in
numbers, eg 19)


Top-right shadow
 
Bottom-left shadow Bottom shadow