In previous tutorial "Introduction to Network Programming using TCP/IP ! " : http://programmingethicalhackerway.blogspot.in/2015/07/introduction-to-network-programming.html, We had learned about socket functions. In this tutorial, we will look at how these functions are used by server-client application. Before we proceeding, let's first we understand what exactly is the server-client ? If i say in simple words, a server is one who serve services and client is one who receive services from server. Consider a case, you are writing a program which hack the victim's computer. The idea of the program may be you are a server and your victim is client. You wrote a malicious client program which spawn shell and send it to the attacker's IP address. Now you send this client program to your victim and whenever your victim run this program, game will over. So, Your victim send shell (cmd.exe or bin/bash) to you and you receive the shell on your server.
I hope now you get some basic idea of client-server concept. Let us first write server code , then client code. Don't get panic after looking code. I will describe each and every line in detail later.
server.c
Now i will explain step by step.
The header file #include <sys/types.h> contains definitions of a number of data types used in system calls.
The header file #include <netinet/in.h> contains constants and structures needed for internet domain addresses.
The header file #include <sys/socket.h> includes a number of definitions of structures needed for sockets.
The Two variables fd and newfd are file descriptors and store the values returned by the socket system call and the accept system call. clienlen stores the size of the address of the client. num is the return value for the read() and write() calls.
A sockaddr_in is a structure containing an internet address.We have already discussed about this structure in our previous tutorial.
The socket() system call creates a new socket. It takes three arguments as we already discussed previously. If the socket call fails, it returns -1.
The setsockopt() function allow us to reuse a given address for binding. Without this option set, when the program tries to bind to a given port, it will fail if that port is already in use.
The variable server is a structure of type struct sockaddr_in. This structure has four fields and set accordingly our requirement.
Now The bind() call passes the socket file descriptor, the address structure, and the length of the address structure.
The listen() call tells the socket to listen for incoming connections. It takes two arguments. The first argument is the socket file descriptor, and the second is the the number of connections that can be waiting.
The accept() call actually accepts an incoming connection.The accept() system call causes the process to block until a client connects to the server.It takes three arguments. The accept() function returns a new socket file descriptor for the accepted connection. This way, the original socket file descriptor can continue to be used for accepting new connections, while the new socket file descriptor
is used for communicating with the connected client.
Once a connection has been established, everything written by the client will be read by the server, and everything written by the server will be read by the client. So when our connection has been established, we will receive a message from our client and then our server send a message "Received your message. Good Bye!" to the client.
if this code is still not clear to you, then i would recommend you:
1 . C programming for hackers.
2. Introduction to Network Programming using TCP/IP !
In the next post, we will discuss about client program.
If you like this post or have any question, please feel free to comment!
I hope now you get some basic idea of client-server concept. Let us first write server code , then client code. Don't get panic after looking code. I will describe each and every line in detail later.
server.c
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <arpa/inet.h>
- #define port 8080
- int main()
- {
- int fd, newfd, serlength, clienlength, num;
- int yes =1;
- struct sockaddr_in server;
- struct sockaddr_in clienlen;
- char buffer[1024];
- char *msg = "Recived your message. Good Bye\n";
- fd=socket(AF_INET, SOCK_STREAM, 0);
- if (fd < 0)
- perror("Error in Opening socket");
- if (setsockopt(fd,SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
- perror("Error in reusing address\n");
- server.sin_family=AF_INET;
- server.sin_addr.s_addr=INADDR_ANY;
- server.sin_port=htons(port);
- serlength=sizeof(server);
- if (bind(fd, (struct sockaddr *)&server, serlength) < 0)
- perror("Error in binding socket");
- clienlength=sizeof(clienlen);
- if (listen(fd,10) < 0)
- perror("Error in listening");
- while (1) {
- newfd =accept(fd, (struct sockaddr *)&clienlen, &clienlength);
- if (newfd < 0)
- perror("Error in Accepting");
- printf("A connection has been accepted from %s\n", inet_ntoa((struct in_addr)clienlen.sin_addr));
- num = recv(newfd,buffer,1023,0);
- printf("Recieve %d bytes from client\n",num);
- if (num == -1) {
- perror("Error in Reading");
- }
- else {
- buffer[num]='\0';
- printf("Message from client : %s\n",buffer);
- serlength = strlen(msg);
- num = send(newfd,msg,serlength,0);
- if (num < serlength)
- perror("Error in writing");
- if (close(newfd) == -1)
- perror("Error in closing");
- }
- }
- }
Now i will explain step by step.
The header file #include <sys/types.h> contains definitions of a number of data types used in system calls.
The header file #include <netinet/in.h> contains constants and structures needed for internet domain addresses.
The header file #include <sys/socket.h> includes a number of definitions of structures needed for sockets.
The Two variables fd and newfd are file descriptors and store the values returned by the socket system call and the accept system call. clienlen stores the size of the address of the client. num is the return value for the read() and write() calls.
A sockaddr_in is a structure containing an internet address.We have already discussed about this structure in our previous tutorial.
The socket() system call creates a new socket. It takes three arguments as we already discussed previously. If the socket call fails, it returns -1.
The setsockopt() function allow us to reuse a given address for binding. Without this option set, when the program tries to bind to a given port, it will fail if that port is already in use.
The variable server is a structure of type struct sockaddr_in. This structure has four fields and set accordingly our requirement.
Now The bind() call passes the socket file descriptor, the address structure, and the length of the address structure.
The listen() call tells the socket to listen for incoming connections. It takes two arguments. The first argument is the socket file descriptor, and the second is the the number of connections that can be waiting.
The accept() call actually accepts an incoming connection.The accept() system call causes the process to block until a client connects to the server.It takes three arguments. The accept() function returns a new socket file descriptor for the accepted connection. This way, the original socket file descriptor can continue to be used for accepting new connections, while the new socket file descriptor
is used for communicating with the connected client.
Once a connection has been established, everything written by the client will be read by the server, and everything written by the server will be read by the client. So when our connection has been established, we will receive a message from our client and then our server send a message "Received your message. Good Bye!" to the client.
if this code is still not clear to you, then i would recommend you:
1 . C programming for hackers.
2. Introduction to Network Programming using TCP/IP !
In the next post, we will discuss about client program.
If you like this post or have any question, please feel free to comment!