Socket Programming using TCP/IP
Socket programs are used to communicate between various processes usually running on different systems. It is mostly used to create a client-server environment. This post provides the various functions used to create the server and client program and an example program. In the example, the client program sends a file name to the server and the server sends the contents of the file back to the client.
Functions used in server program:
- socket() –
This call creates an unnamed socket and returns a file descriptor to the calling process.
usage : int socket(int domain, int type, int protocol)
Eg: sockfd=socket(AF_INET,SOCK_STREAM,0);
here AF_INET means the the communication is over the internet domain.SOCL_STREAM indicates its a stream type of communication and 0 indicates the protocol used is TCP/IP.
- bzero()-
this call is used set all the values of the buffer to zero.
usage: bzero(pointer_to_buffer,size_of_buffer)
eg: bzero((char *)&serv_addr,sizeof(serv_addr));
here serv_addr is of the struct type sockaddr_in which has members used to describe the complete address of a system.
- serv_addr.sin_family=AF_INET;
As stated earlier the serv_addr has severaal members and the first of it is sin_family and it contains the code for the address family and is always AF_INET, indicating the internet domain.
- serv_addr.sin_addr.s_addr=INADDR_ANY;
here sin_addr has one member s_addr which is used to hold the IP address of the machine its running in, and this IP ddress is got from the INADDR_ANY constant.
- serv_addr.sin_port=htons(portno);
here we hav to store port number into he sin_port member and this takes on the network bute order. So, htons() converts the host byte order representation of the port number to network byte order representation.
- bind() –
It is a system call that binds a socket to an address. Here, the address would be the IP address of the current machine and the port number.
usage : bind(socket_fd, pointer_of_address_its_bound_to, size_of_address);
Eg: bind(sockfd, (struct sockaddr *)&serv_addr,sizeof(Serv_addr)_);
On failure, it returns a value less than zero.
- listen() –
This call allows a process to listen on socket for communication.
usage: listen(socket_fd, no_of_waiting_connections);
so it takes in a socket file descriptor and the no. of connections waiting while the process is handling a particular connection. so they wait in a blocking queue.
Eg : listen(sock_fd,5);
so 5 connections can wait at the max.
- accept() –
is a system call that causes the process to block until the client connects to the server.
it returns a new descriptor and all communication should be carried out using the new file descriptor.
usage: int accept(sockfd,pointer_to_address_of client, addr_storing_size_of_client_address);
Eg: newsockfd= accept(sockfd, (struct sockaddr *)&cli_addr,&clilen);
here cli_len=sizeof(cli_addr); so the newsockfd has the new socket address which will be used for communication.
So, this command blocks until the read() of data is complete that is till the client has finished its write().
- bzero(buffer,4096);
n=read(newsockfd,buffer,4096);
this initializes the buffer to zero and then reads the content from the socket (using the newsockfd) into the buffer. Her since the client sends the file name first, the buffer now contains the filename whose contents has to be sent back. The read(), will also block the process till there is something remaining to read from the socket.
- fd=open(buffer,O_RDONLY)
opens the file requested by the client in the read only mode.
- read(fd,buffer,4096);
this reads the contents of the file into the buffer. In socket programming, all communications happens using the buffer both at client and server side. With the completion of this read , the contents of the file is residing in the buffer and is ready to be sent to the client.
- write(newsockfd,buffer,4096);
this is the final command ehich writes the contents of the buffer( which has the file content) into the socket using the newsockfd which finally delivers it to the client process.
Functions used in client program:
-
connect() – is a function used by the client to establish a connetion to the server. It takes 3 arguements:
usage: connect(sockfd, host_to_which_itconnects, sizeof_addr);
Eg: connect(sockfd,(struct sockaddr*)&serv_addr,sizeof(Serv_addr))<0);
-
The client too like the server uses the write() to send the file name to server and uses read() to read the content of the file into the buffer. It finally uses write(1,buffer,4096) to print the content on file onto standard output.
The full source code and usage for the client and server can be found here.