Introduction to Socket Programming with PHP
Pages: 1, 2
Sockets programming in PHP
In the game, the small men were actually network sockets, and the controls represented my favorite programming language -- PHP!
The network sockets support in PHP doesn't include the most advanced features (yet) like the C implementation does, but it's probably enough for 95 percent of all network applications, and that's not bad at all. Also, you'll be able to write real network applications using such an easy-to-use language as PHP. Let's look at a simple TCP server. See listing 1 here.
Actually, the similarities between this program, and the made-up game we looked at earlier are quite clear. Let's discuss this for a moment. First, on line 8, we use
set_time_limit(0) to tell PHP that we want to be able to wait for connections for an unlimited amount of time. This is the same as telling the men to wait by the hatch forever (or at least until we explicitly tell them to go away from there).
On lines 11 through 15, we create a new socket. This is known as the global socket and will be the one that checks for incoming connections. (In the analogy, this socket is represented by the man in control of the hatch in Computer I.) For this, we use the
socket() function, which takes a total of three arguments. However, I won't try to explain these parameters, and then call this article an introduction to network programming. By the time you need to specify any other arguments than the ones we use here, you'll be quite into network programming already. However, one thing that can be good to know is that the second argument,
SOCK_STREAM declares that we want to use the
TCP protocol (in contrast to UDP).
On lines 18 through 22, the newly created socket is bound to an IP address and a port. Since we're going to run this program on our local machine only, we use 127.0.0.1 as the IP address. The port we use, 10000, is picked at random. You can actually use any port between 1024 and the 65535 that isn't already in use. To draw a parallel to the analogy -- this is the same as telling one of the small men which network connection (hatch) to control, and what specific network data he is responsible for. If a packet arrives, which claims to be destined for port 10000, our small man knows that he is the one to take care of it (Yes, this may sound weird, but the small men actually can speak to the data packets!).
With the introduction of ports, you've probably already understood that there can be many men waiting for something to arrive at the same hatch. The port where the data is sent decides if one particular man should take care of the incoming data or not. So, our man will only care about the data that's going to port 10000.
Until now, we've just informed the man of what he should do, but we haven't really sent him instructions yet. This is done on lines 28 through 31 where we tell the man move from his sofa and get to the hatch. On lines 34 through 38, we also tell him stay there and open the hatch if it's needed. In programming terms, the
accept_connect() function will wait until a connection arrives. So, the program will stop executing here until we use telnet on it a little later. Also note that when a connection is detected,
accept_connect() will create another socket, called
$msgsock, which will handle the communication with the connecting side. This is the third man that showed up in Figure 4 (he took care of the incoming data).
On lines 41 through 46, we send the visitor our welcome message using the
write() function. Note that this is done by
$sock is busy with his hatch, remember? At this stage, the
accept_connect() function has already detected a connection, and therefore the execution of the script has reached this far. Or, in the analogy, the man saw something coming, opened the hatch, and asked the packet where it was going. The packet answered "port 10000", so he let it in and passed it to his helper,
On lines 49 through 54, something quite interesting happens. Here, we tell the second man,
$msgsock, to go and wait at the hatch as well. This is to make sure he is ready when
$sock lets in something he needs to take care of. In programming terms, we use
read() to read data from our connection. However, for us to be able to receive any data, it first has to be sent from the other end. Like
read() command will wait until something happens. When data has arrived for port 10000, the second man,
$msgsock, will take it and show it the way to the
$buf variable. So, we now have that data in
$buf and can send back a nice reply on lines 57 through 61. Again,
$msgsock will take care of this, and
$sock will just open and close the hatch.
The last thing we do in this script is tell both men,
$msgsock to go home and take a rest (lines 64 and 67). Or in more technical terms, we close both sockets and the network connection.
Testing our TCP server
Okay, it's time for testing -- always the most exciting part. However, before you try to execute the script, make sure you have the right permissions on it:
chmod 755 lst01.php
Also make sure that the first line of the script points at your PHP binary. Then, start the server:
(If you get an error saying that the
socket() function is undefined, you need to get into your PHP source directory, run
./configure --enable-sockets, and then recompile and reinstall the PHP binary by running
make && make install.)
Now, open another terminal, and issue the following command:
telnet 0 10000
This means you want to establish a telnet connection to your local machine, and you want to use port 10000. If everything is okay, you should now get the following output:
Trying 0.0.0.0... Connected to 0. Escape character is '^]'. Welcome to my TCP server!
Now, write someting and press enter:
Hello You said: Hello Connection closed by foreign host.
Isn't that cool? It's not very advanced, but we actually created a real network connection and exchanged some information through it.
In this article, you learned how to exchange data between two computers using network sockets. I hope you found the figures and explanations useful. The key to becoming a successful programmer is to understand what is actually happening behind a certain function call. When you can do that, you will be able to truly take control of your program.
Remember, network programming is all about sending and receiving data over a network connection. We did both today, so what's stopping you?
Daniel Solin is a freelance writer and Linux consultant whose specialty is GUI programming. His first book, SAMS Teach Yourself Qt Programming in 24 hours, was published in May, 2000.
Discuss this article in the O'Reilly Network PHP Forum.
Return to the PHP DevCenter.