Lets face it, networking is cool. Nothing beats being able to connect computers together and send data back and forth. But how do programs do that? How can you communicate with other computers? One method is to use BSD Sockets. BSD Sockets is an mechanism that lets computers communicate with each other. Fortunately, sockets are really easy to program, and only have a few gotchas. I am only going to cover the common case of stream sockets in the Internet domain. There are other types of sockets: datagram, raw, sequenced packets, and esoteric ones like reliably-delivered message sockets. Forget those for now. When I use the term "sockets" in this article I mean "stream sockets in the Internet domain".

Communicating with a remote computer using sockets is done using the following steps:

  1. Create a socket using socket().
  2. Connect the socket to the remote computer using connect ().
  3. Read and write data onto the socket using read() and send().

Step 1 is easy:

If socket() returns less than 0 then there was an error in creating the socket.

Step 2 is also easy but requires jumping through some hoops to resolve the IP address. Here is all the code you need to connect to a remote computer given a hostname or IP:

h_addr,hp->h_length); server.sin_port=htons(atoi(port)); printf("Connecting to %s (%s) on port %s...\n",servername, inet_ntoa(server.sin_addr),port); fflush(stdout); if (connect(csock,(struct sockaddr *)&server, sizeof server)<0) { perror("Connecting stream socket"); exit(1); } printf("Connected.\n"); ]]>

At this point you are connected to the remote computer.

Step 3 is also easy, however there are a few points to remember. If you try to read() on a normal socket and there is no data being sent from the remote computer it will "block". In otherwords, the program will hang at that point until data gets sent to you. This is in general a bad idea. Fortunately, there is a way around this. Using select() you can check to see if there is data waiting to be read on the socket. Here is some code to read data off a socket:

0 if there is a read event on the socket // e.g. data waiting to be read sr=select(csock+1, &rread, (fd_set *)0, (fd_set *)0, &to); if (sr < 0) { perror("select"); continue; } // there was an event on the socket if (sr> 0) { // yeah. data is waiting to be read if (FD_ISSET(csock,&rread)) { // read the up to 2999 bytes from inbound socket if ((rval=read(csock,buf,2999)) <= 0) { // the other end of the socket has closed printf ("ending connection\n"); socketopen=0; } else // terminate the string // in the buffer buf[rval]=0; } else // No data was waiting to // be read. Do some other // thing here. do_some_other_stuff_here(); // loop until remote // socket closes. } while (socketopen); } ]]>

Select lets you check to see if there is an event occuring on the socket.. Events can can be:

  1. Data waiting to be read.
  2. Socket is ready to write to.
  3. There is an exceptional condition. This occurs when out of band data is pending. This is out of scope for this article.

For case 1 you want to do:

For case 2 you want:

You can also check for muliple cases by doing:

Basically, passing a fd_set structure as the 2nd argument tells select that you are looking for read events, passing a fd_set structure as the 3rd argument tells it you are looking for write events.

Before you pass these fd_set structures you have to make sure that they are initialized properly by doing:

The FD_SET indicates that we only want to check the csock socket. It is possible to check multiple sockets at the same time, but that is left as an excercise for the reader.

Writing to a socket is very easy. You can use select() with case 2 to make sure the socket is ready to be written and then do:

Where buf contains the data you want to send and len is the number of bytes in buf. The last parameter is used for esoteric purposes is are out of the scope of the article.

You can close your socket elegantly by doing the following:

Thats all there is to connect to a server and send and receive data. Next issue I will talk about how to create your own server program. Its a little more complex, but not much.