Creating 1 way connection among Client and Server using c Lang.
Tags: socketprogramming, c
Published: 2022-06-18 11:11:56

Many of us have studied Computer Networks. It is the subject that provides us the main concepts regarding Data Communication and Networks.

Computer Networks divides the whole system into some steps which are the layers of different model.

The two main models of Computer Networks are OSI model (Open System Interconnection) and TCP/IP model (Transmission Control Protocol/Internet Protocol).

To sum up we have basic knowledge about the networks,their topologies, LAN, WAN, MAN, different devices,how these devices works on different layers, different protocols and algorithms etc.

But when it comes to socket programming many of us fear to write code.
So here I am presenting how to set up one way connection among the client and server.

## Prerequistics

1. C Language.
2. Computer Network Basics.

## System Requirement and Language

1. Implementation will be on C Language.
2. Linux System is required to perform the task.

## Introduction to socket and socket programming

What is a Socket actually? 

Socket in nothing but the combination of the IP address and the Port Number. In the transport Layer, process to process delivery is occured, and for this port number is also required along with the IP address of the system.

In order to establish connection among the client and server, both the server and the client need to create socket.

To write code for socket, we use a pre-built structure in C Language, `struct sockaddr` and `struct sockaddr_in` which comes under the header `<netinet/in.h>`

struct sockaddr contains,

```
struct sockaddr {
  unsigned short sa_family; // address family, AF_xxx
  char sa_data[14]; // 14 bytes of protocol address
}; 
```
and struct sockaddr_in contains,

```
struct sockaddr_in {
  short int sin_family; // Address family
  unsigned short int sin_port; // Port number
  struct in_addr sin_addr; // Internet address
  unsigned char sin_zero[8]; // Same size as struct sockaddr
};
```
In the above structure you could see different variables,
so basically `sin_family` stores the Address family of the IP Address like if it is IPv4 we use `AF_INET` and if it is IPv6 we use `AF_INET6`,
`sin_port` stores the port number,
`sin_addr` is a variable of another struct type `in_addr` whic is defines as:-

```
struct in_addr {
  uint32_t s_addr; // that's a 32-bit int (4 bytes)
};
```

## Flowchart showing the connection.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fpgamk38leozooiamo6p.png)

_Image Source: GFG_

As shown in the above message first we need to create socket for both client and server side.

To create socket, `socket()` function is used. It comes under the header `<sys/socket.h>`.

Syntax of `socket()` is:-
```
int socket (int domain,int type,int protocol);
```
here, `domain` is family of the network, for IPv4 it is `AF_INET` and for IPv6 it is `AF_INET6`,
`type` is the socket type, for UDP we use `SOCK_DGRAM` and for TCP we use `SOCK_STREAM`,
and the third argument `protocol` stores the protocol value used in the program. For default protocol we use 0.

**Now in server side,**

We need to bind the address, i.e we need to cast the `struct sockaddr_in` to `struct sockaddr` type or we can say that we have to associate the socket with the local address.
and for this task `bind()` function is used, which comes under the header `<sys/socket.h>`.

Syntax for `bind()` is:-
```
int bind(int s_fd,struct sockaddr *s_addr,int s_len);
```
where `s_fd` is the file descriptor returned by the socket of the server, `s_addr` is the pointer to the `sockaddr` and `s_len` is the length of the `s_addr`.If it returns -1 then that means binding process is unsuccessfull.

Then we need to listen for the clients, and for this purpose we use `listen()` function which also comes under the same header  `<sys/socket.h>`.

Syntax for `listen()` is:-
```
int listen(int s_fd, int backlog);
```
where `s_fd` is the file descriptor returned by the socket, and `backlog` is the total client limit of the socket. If it returns -1 then that means listening process is unsuccessfull.

The next step is to start accepting the clients, and for this `accept()` function is used. This function also comes under the header `<sys/socket.h>`.

Syntax for accept():-
```
int accept(int s_fd, struct sockaddr *c_addr, int *c_len);
```
where `s_fd` is the file descriptor returned by the socket of the server, 
c_addr is the pointer to `sockaddr` of the client file descriptor and `c_len` is the pointer to the length of `c_addr`. It return the socket file descriptor of the client. If it return -1 that mean the process is unsuccessfull.

After these steps one can start writing message to the client using `write()` function and vice-versa.

 **For Client side**
After creating sockect,a client starting connection with the server using `connect()` function. It is belong to the same header `<sys/socket.h>`.

Syntax of `connect()` is:-
```
int connect(int cfd, const struct sockaddr *c_addr, c_len);
```
where `cfd` is the file descriptor returned by the socket of the client, `c_addr` is the pointer to the `sockaddr` and `c_len` is the size of `c_addr`. If the function returns -1 then it means that the connection is not successfull.

After this step client can connect with the server and can read data written by the server and vice-versa.

## Let's begin with the code

**Server Code**
Let us first try to implement the required headers.

```
#include<stdio.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<string.h>
#include<stdlib.h>
```
Here,`<unistd.h>` is used to make use of functions like read() and write().
`<stdlib.h>` is for exit() and
`<string.h>` is for strcmp() and other string functions.

Now let's implement the `socket()` function. 
```
struct sockaddr_in s_addr;    
                        
int s_fd,s_len;

if((s_fd = socket(AF_INET,SOCK_STREAM,0))==-1){				
	printf("[-]Error in Socket\n");
        exit(0);
}
printf("[+]Server Socket created\n");
	

s_addr.sin_family = AF_INET;                                  
s_addr.sin_port = 3452;                                       
s_len=sizeof(s_addr); 
```

Let's implement the other functions i.e.
`bind()`,`listen()` and `accept()`

```
if(bind(s_fd,(struct sockaddr*)& s_addr,s_len)==-1){		   
		printf("[-]Error in binding\n");
        exit(0);
    }
	printf("[+]Binding successfull\n");

	if(listen(s_fd,5)==-1){                                     
		printf("[-]Error in listen\n");
        exit(0);
    }
	printf("[+]Listening... \n");


    c_len=sizeof(c_addr);                                 	
	if((c_fd=accept(s_fd,(struct sockaddr*)&c_addr,&c_len))==-1){
		printf("\n[-]Error in accepting\n");
        exit(0);
    }
	printf("[+]New Client Connected!!!: \n\n");
```

The final code will look like :-
**server.c**
```
#include<stdio.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<stdlib.h>

int main()
{
	struct sockaddr_in s_addr,c_addr;    
                          
	int s_fd,c_fd,s_len,c_len;



	if((s_fd=socket(AF_INET,SOCK_STREAM,0))==-1){				
		printf("[-]Error in Socket\n");
        exit(0);
    }
	printf("[+]Server Socket created\n");

	s_addr.sin_family = AF_INET;                                  
	s_addr.sin_port = 4000;                                       
	s_len=sizeof(s_addr); 

	if(bind(s_fd,(struct sockaddr*)& s_addr,s_len)==-1){		   
		printf("[-]Error in binding\n");
        exit(0);
    }
	printf("[+]Binding successfull\n");

	if(listen(s_fd,5)==-1){                                     
		printf("[-]Error in listen\n");
        exit(0);
    }
	printf("[+]Listening... \n");


    c_len=sizeof(c_addr);                                 	
	if((c_fd=accept(s_fd,(struct sockaddr*)&c_addr,&c_len))==-1){
		printf("\n[-]Error in accepting\n");
        exit(0);
    }
	printf("[+]New Client Connected!!!: \n\n");

    char buff[100];

	while(1)
	{   
        read(c_fd,buff,100);									  
        printf("From Client: %s\n",buff);           
		if (strcmp(buff, "Disconnected\n") == 0){
                printf("[-]Client Disconnected");
                break;
            }
	}
    close(c_fd);
	return 0;
}
```

Similarly client code will be:-
**client.c**
```
#include<stdio.h>
#include<unistd.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<string.h>
#include<stdlib.h>

int main()
{
        struct sockaddr_in c_addr;                                 
        int c_fd,c_len;
    	char buff[100];
        char buff1[2]; 

        if((c_fd=socket(AF_INET,SOCK_STREAM,0))==-1){			 
        	printf("[-]Error in Socket\n");
            exit(0);
        }
        printf("[+]Client Socket created\n");

        c_addr.sin_family=AF_INET;                                    
        c_addr.sin_addr.s_addr=INADDR_ANY;                       
        c_addr.sin_port=4000;                                     
        c_len=sizeof(c_addr); 

        if(connect(c_fd,(struct sockaddr*)& c_addr,c_len)==-1) { 
        	printf("[-]Error in Connect\n");
            exit(0);
        }
        printf("[+]Connected to the Server: \n\n");
        while(1)
        {
            printf("Enter your Message Mr.Client: ");
            fgets(buff,sizeof(buff),stdin);
              
            if (strcmp(buff, "Exit\n") == 0){
                printf("[-]Disconneted from Server");
                write(c_fd,"Disconnected\n",100);
                break;
            }
            else{
                write(c_fd,buff,100);
            }
        }       
        close(c_fd);                                              
        return 0;
}
```
Thanks for going through this little blog. If you find any thing wrong please comment below. Don't hesitate to give feedbacks and suggestions.