Most operating systems provide precompiled programs that communicate across a network. Common examples into the TCP/IP world are web clients(browsers) and web servers, and the FTP and TELNET clients and servers. Sometimes when we are using this utilities of the internet we don't think about all the process involved. To better understand this aspects we, in our research group(GTI, Grupo de Tecnologia em Informática) at Goias Catholic University (Universidade Católica de Goiás), decide to build, write our own network programs, mini-chat, using the basic structure about sockets, an application program interface or API, that mechanism that make all this communication possible over the Net.
We examine the functions for communication through sockets. A socket is an endpoint used by a process for bi-directional communication with a socket associated with another process. Sockets, introduced in Berkeley Unix, are a basic mechanism for IPC on a computer system, or on different computer systems connected by local or wide area networks(resource 2). To understand some structs into this subject is necessary a deeper knowledge about the operating system and his networking protocols. This subject can be used as either beginners programmers or as a reference for experienced programmers.
Most network applications can be divided into two pieces: a client and a server.
Creating a socket
#include <sys/types.h> #include <sys/socket.h>
When you create a socket there are three main parameters that you have to specify:
int socket(int domain, int type, int protocol);
The Domain parameter specifies a communications domain within which communication will take place, in our example the domain parameter was AF_INET, that specify the ARPA Internet Protocols The Type parameter specifies the semantics of communication, in our mini chat we used the Stream socket type(SOCK_STREAM), because it offers a bi-directional, reliable, two-way connection based byte stream(resource 2). Finally the protocol type, since we used a Stream Socket type we must use a protocol that provide a connection-oriented protocol, like IP, so we decide to use IP in our protocol Type, and we saw in /etc/protocols the number of ip, 0. So our function now is:
s = socket(AF_INET , SOCK_STREAM , 0)where 's' is the file descriptor returned by the socket function.
Since our mini chat is divided in two parts we will divided the explanation in the server, the client and the both, showing the basic differences between them, as we will see next.
Like all services in a Network TCP/IP based, the sockets are always associated with a port, like Telnet is associated to Port 23, FTP to 21... In our Server we have to do the same thing, bind some port to be prepared to listening for connections ( that is the basic difference between Client and Server), Listing 2. Bind is used to specify for a socket the protocol port number where it will be waiting for messages.
So there is a question, which port could we bind to our new service? Since the system pre-defined a lot of ports between 1 and 7000 ( /etc/services ) we choose the port number 15000.
The function of bind is:
int bind(int s, struct sockaddr *addr, int addrlen)
The struct necessary to make socket works is the struct sockaddr_in address; and then we have the follow lines to say to system the information about the socket.
address.sin_family = AF_INET /* use a internet domain */
address.sin_addr.s_addr = INADDR_ANY /*use a specific IP of host*/
address.sin_port = htons(15000); /* use a specific port number */
And finally bind our port to the socket
bind(create_socket , (struct sockaddr *)&address,sizeof(address));
Now another important phase, prepare a socket to accept messages from clients, the listen function is used on the server in the case of connection oriented communication and also the maximum number of pending connections(resource 3).
listen (create_socket, MAXNUMBER)
where MAXNUMER in our case is 3. And to finish we have to tell the server to accept a connection, using the accept() function. Accept is used with connection based sockets such as streams.
accept(create_socket,(struct sockaddr *)&address,&addrlen);
As we can see in Listing 2 The parameters are the socket descriptor of the master socket (create_socket), followed by a sockeaddr_in structure and the size of the structure.(resource 3)
Maybe the biggest difference is that client needs a Connect() function. The connect operation is used on the client side to identify and, possibly, start the connection to the server. The connect syntax is
connect(create_socket,(struct sockaddr *)&address,sizeof(address)) ;
A common structure between Client and the Server is the use of the struct hostent as seeing in Listing 1 and 2. The use of the Send and Recv functions are another common codes.
The Send() function is used to send the buffer to the server
send(new_socket,buffer,bufsize,0);
and the Recv() function is used to receive the buffer from the server, look that it is used both in server and client.
recv(new_socket,buffer,bufsize,0);
Since the software of the TCP/IP protocol is inside the operating system, the exactly interface between an application and the TCP/IP protocols depends of the details of the operating system(resource 4).In our case we examine the UNIX BSD socket interface because Linux follow this. The Mini-chat developed here is nothing more than a explain model of a client/server application using sockets in Linux and should be used like a introduction of how easy is to develop applications using sockets. After understand this you can easily start to think about IPC (interprocess Communication), fork, threads(resource 5) and much more. The basic steps to make it work is:
This example was the start of our server program in our last project, a network management program. Here are the source listings: