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

15.1.5     Sockets can be powerful

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

OK, so a ROT13 system is not very helpful, so I would not be surprised if you were wondering whether sockets could be made to do anything useful . Well, consider what socket applications you use - what relies on sockets to work?

One of the simplest systems is a web server - an application that listens for requests on a given port, and serves up the files that are asked for. Naturally web servers do a lot more than that - they have to receive POST data, handle file uploads, permissions, filters, and lots more, but we're only interested in the most basic task: serving files.

Your average HTTP request will look like this:

GET /somefile.txt HTTP/1.1
HOST: www.foo.com

Out of all that, we can ignore everything but "/somefile.txt" - that is the file we need to serve up. So, our server waits listening for connections and requests, sending out files as appropriate. Each HTTP response needs to take a very specific format because HTTP splits its response into "header" and "content". The header part can contain several lines of header information, such as the name of the file being served, its size, its type, the name of the server, etc, but it always contains the HTTP response type. The content part is the file itself, and is separated from the header by two sets of carriage return/line lines.

The HTTP response type is one line of text that contains the HTTP version being used (usually 1.0 or 1.1), followed by the status code of the response and a small amount of text explaining the status. The status code is meant for the web browser, whereas the text is meant for the person actually using it - browsers are under no obligation to display or indeed do anything with the text you send along with the status code.

The content type is particularly important because it tells browsers how to handle the file being sent - this uses a standard known as Multipurpose Internet Mail Extensions (MIME) to define the exact type of data. Some of the various MIME types will be discussed in more detail later - for now you just need to know that the MIME type for HTML is "text/html", and for PNG images it is "image/png".

Without further ado, here is a very basic web server written using PHP:

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

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

    while (
true) {
        
$client = socket_accept($socket);
        
$input = trim(socket_read ($client, 4096));
        
$input = explode(" ", $input);
        
$input = $input[1];
        
$fileinfo = pathinfo($input);

        switch (
$fileinfo['extension']) {
            case
"png";
                
$mime = "image/png";
                break;
            default:
                
$mime = "text/html";
        }

        if (
$input == "/") {
            
$input = "/index.html";
        }

        
$input = ".$input";

        if (
file_exists($input) && is_readable($input)) {
            print
"Serving $input\n";
            
$contents = file_get_contents($input);
            
$output = "HTTP/1.0 200 OK\r\nServer: APatchyServer\r\nConnection: close\r\nContent-Type: $mime\r\n\r\n$contents";
        } else {
            
$contents = "The file you requested does not exist. Sorry!";
            
$output = "HTTP/1.0 404 OBJECT NOT FOUND\r\nServer: APatchyServer\r\nConnection: close\r\nContent-Type: text/html\r\n\r\n$contents";
        }

        
socket_write($client, $output);
        
socket_close ($client);
    }

    
socket_close ($socket);
?>

If you start that script up, you should be able to get to it through your web browser by visiting http://localhost:8000. You will need to put a little content in there to make it work at its best - if you create a small HTML file with PNG pictures in, the server should be able to serve it all up to a web browser.





<< 15.1.4 Sockets can be servers: socket_create_listen(), socket_accept(), socket_write(), socket_read(), and socket_close()   15.2 Domain resolution functions: dns_check_record(), dns_get_mx(), and dns_get_record() >>
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
Frank - 06 Sep 2008

Alex is right - but it also doesn't work on WinXP in PHP 5.2.2.

Alex - 06 Sep 2008

Okay.. in case anyone decides to get a bright idea to write their own socket server... socket_create_listen appears to be buggy at least on Win2k in PHP 5.0.4 in that it doesn't listen on anything other than the localhost interface (even though the docs say it listens on all interfaces).

The workaround is to use the longer method - socket_create, socket_bind, socket_listen. That seems to work - use "0.0.0.0" for the address to bind to, and then it will listen on any interface.



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 seven plus ten?
The answer is:
(please write in
numbers, eg 19)


Top-right shadow
 
Bottom-left shadow Bottom shadow