Socket programming

25
Socket Programming Socket Programming In C Language Written By :- R.Rajivarnan ( Cyber Security Researcher ) http://www.akati.com

Transcript of Socket programming

Socket Programming

Socket Programming In C Language

Written By :- R.Rajivarnan ( Cyber Security Researcher ) http://www.akati.com

P a g e | 1

Introduction

This Tutorial is On Socket Programming In C Language for Linux. Instructions Give Below will only work

On Linux System not in windows.

Socket API In windows is called Winsock and there we can discuss about that in another tutorial.

What is Socket?

Sockets are a method for communication between a client program and a server program in a network.

A socket is defined as "the endpoint in a connection." Sockets are created and used with a set of

programming requests or "function calls" sometimes called the sockets application programming

interface (API).

The most common sockets API is the Berkeley UNIX C interface for sockets.

Sockets can also be used for communication between processes within the same computer.

Forming Internet (IPv4) Socket Addresses

struct sockaddr_in {

sa_family_t sin_family; /* Address Family */

uint16_t sin_port; /* Port number */

struct in_addr sin_addr; /* Internet address */

unsigned char sin_zero[8]; /* Pad bytes */

};

Struct sockaddr {

unsigned short sa_family /*Family Protocol*/

char sa_data[14]; /*actually longer; address value*/

};

P a g e | 2

/ * Structure of DNS entries * /

struct hostent {

char *h_name; /* official name of host */

char **h_aliases; /* alias list */

int h_addrtype; /* host address type */

int h_length; /* length of address */

char **h_addr_list; /* list of addresses */

}

#define h_addr h_addr_list[0] /* for backward compatibility */

The members of the hostent structure are:

h_name - The official name of the host.

h_aliases - An array of alternative names for the host, terminated by a NULL pointer.

h_addrtype - The type of address; always AF_INET or AF_INET6 at present.

h_length - The length of the address in bytes.

h_addr_list - An array of pointers to network addresses for the host (in network byte order),

terminated by a NULL pointer.

h_addr - The first address in h_addr_list for backward compatibility.

Sockets are Virtual parts of each type of communication network made by the two hosts on a link.

For example, when you type www.google.com in your browser, it opens socket and then makes the

connection to google.com to compare with the website and then connects back to you.

The same thing happens in gtalk or skype. Any Communication networks wandering for socket

connection.

Socket API In Linux is similar to socket in BSD/UNIX. Although in Socket API is Different in Some Systems.

And now with New Standard is POSIX sockets API which is similar to the BSD sockets.

To understand this tutorial you should have little knowledge of language C and pointers.You must have

gcc compilers which are installed on your Linux system. An idea that together with gcc would be better. I

would recommend you Geany because you can edit and run a program in without much configuration.

In Ubuntu you can write in terminal apt-get install Geany. We all tutorial are codes that demonstrate

some concepts. You can guide these codes in Geany and immediately see the results for you better

understand concepts.

P a g e | 3

Create Socket

The first thing you should do is to create a socket. Socket function is according to the following code:

1 #include<stdio.h>

2 #include<sys/socket.h>

3

4 int main(int argc , char *argv[])

5 {

6 int socket_desc;

7 socket_desc = socket(AF_INET , SOCK_STREAM , 0);

8

9 if (socket_desc == -1)

10 {

11 printf("Cannot create a socket ");

12 }

13

14 return 0;

15}

Function socket () creates a socket and returns a narrative which can be used in other functions. Above

code will create a socket with these properties.

Address family - AF_INET (Only for version IPv4)

Type - SOCK_STREAM (This means that is the type of TCP socket)

Protocol - 0 [or IPPROTO_IP IP Protocol]

Then may need to connect to a server using socket. We can connect to www.google.com site

Note:-

Besides the type SOCK_STREAM is another type which is called SOCK_DGRAM which is linked

with the UDP protocol. This type of non-Socket called a socket connection. In this tutorial will

adhere socket type SOCK_STREAM or TCP.

P a g e | 4

Connecting socket server

We can connect to a remote server to a specific port. So we need two things, IP address and port

number to which will connect. To connect to a remote server we need to perform some action. The first

is to create a structure with clear values.

struct sockaddr_in server;

See the following code.

// IPv4 AF_INET sockets:

struct sockaddr_in {

short sin_family; // AF_INET, AF_INET6

unsigned short sin_port; // htons(3490)

struct in_addr sin_addr; // structure looks in_addr, below

char sin_zero[8]; // Make 0 if you want.

};

struct in_addr {

unsigned long s_addr; // Upload inet_pton ()

};

struct sockaddr {

unsigned short sa_family; // Family address, AF_xxx

char sa_data[14]; // 14 byte address the protocol

};

Sockaddr_in structure has a member called in_addr sin_addr type which has a s_addr of CLIA is nothing

but an important sentence.

It contains the IP addresses in a long format.

server.sin_addr.s_addr = inet_addr("74.125.235.20");

So you must know the IP address of the server is which will connect. Here we used the IP address of

google.com as an example.

P a g e | 5

Later in need to see how to find the IP address of a domain provided by the user or designated program.

#include<stdio.h>

#include<sys/socket.h>

#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])

{

int socket_desc;

struct sockaddr_in server;

// Creating Socket

socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)

{

printf("Socket can not be created ");

}

server.sin_addr.s_addr = inet_addr("74.125.235.20");

server.sin_family = AF_INET;

server.sin_port = htons( 80 );

//Lidhu ne nje remote server

if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)

{

puts("Error in connection ");

return 1;

}

puts("Connection top ");

return 0;

}

This cannot be made simpler than that. Create a Socket and then connects to the remote server. If you

start the application it must provide "Connected". You need to start the program with root privileges.

If gives error regarding then you do not have access to the Internet or have not started the program

with root privileges. To launch the program in the root you must enter: sudo ./a.

Try out to connect to a port other than 80 and thus you will not link you are provided which provides

that the port is not open for about

Ok, now we are connected. Let's do something else, to transmit some data in remote server. Links are

acceptable only TCP Socket. The concept of "connectivity" applies the type of socket -> SOCK_STREAM /

TCP. Connecting through this stream in is reliable.

Suppose this were a slip of not interrupted by other date.

The different Socket such as UDP, ICMP, ARP does not have this concept of connection.

It has non-binding based on communication. Which means you can cost date and receive packages from

anyone.

P a g e | 6

Transfer data over the network

The function send () will simplify working to transfer date, this will descriptors Socket, the data will

transfer and its size. Here you are given a very clear example for the transfer of certain data to a

google.com ip:

#include<stdio.h>

#include<string.h> //strlen

#include<sys/socket.h>

#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])

{

int socket_desc;

struct sockaddr_in server;

char *message;

//Krijo soketin

socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)

{

printf("Connection can not be performed”);

}

server.sin_addr.s_addr = inet_addr("74.125.235.20");

server.sin_family = AF_INET;

server.sin_port = htons( 80 );

// Connect to remote server

if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)

{

puts("Error in connection ");

return 1;

}

puts("I connected \ n ");

// By transferring some data message = "GET / HTTP/1.1\r\n\r\n";

if( send(socket_desc , message , strlen(message) , 0) < 0)

{

puts("Sending data failed ");

return 1;

}

puts("Data were sent \ n ");

return 0;

}

P a g e | 7

In the example above, we start to connect to an IP address and then send the message to type the string

"GET / HTTP / 1.1 \ r \ n \ r \ n" server.

This message actually a protocol http commands to test the main page of a site. Now that we have led

some data, it is time to get reply from the server. So let us make this program a devoted in this way.

Note:-

When you transfer data to a socket we are writing data in this String. This is similar to the type of data in

a file. So you can use the function write () to send data to a String I desired. Later in this tutorial we will

need to use the function write () to send data.

#include<stdio.h>

#include<string.h> //strlen

#include<sys/socket.h>

#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])

{

int socket_desc;

struct sockaddr_in server;

char *message , server_reply[2000];

//creating socket

socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)

{

printf("Cannot create socket ");

}

server.sin_addr.s_addr = inet_addr("74.125.235.20");

server.sin_family = AF_INET;

server.sin_port = htons( 80 );

// Connecting to remote server socket

if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0)

{

puts("Link not top ");

return 1;

}

puts("The connection was made. \ n");

P a g e | 8

// Send some data

message = "GET / HTTP/1.1\r\n\r\n";

if( send(socket_desc , message , strlen(message) , 0) < 0)

{

puts("sending failed ");

return 1;

}

puts("Data were sent successfully \n");

// Receiving a response from the server

if( recv(socket_desc, server_reply , 2000 , 0) < 0)

{

puts("Making failed ");

}

puts("Making finished successfully \n");

puts(server_reply);

return 0;

}

Acquisition of data in Socket

Function recv () is used to receive data from the socket. In the example below we will need to send the

same message as in the example takes up and to get a response from the server

This is the output of the code above:

Connected

P a g e | 9

We can see that this response is sent from the server.

This format is displayed in the form HTML, because in reality it is sent HTML.Google.com site content

that we asked for. Very simple!

Note:-

When receiving data in a String, we read the data correctly if we are this String. This feature is similar to

the read data from a file. So we can use the function read () to read the data in a String. For example :-

1 read (socket_desc, server_reply, 2000);

Now that we got our answer, it is time to close the socket.

Closing the socket

The function close () is used to close a Socket. We have to include library <unistd.h> for this feature.

1 close (socket_desc);

P a g e | 10

Summary

In the example above we learned how to:

1. Create a Socket

2. To connect to a remote server

3. Send some data

4. Take Reply

Your browser thus acts exactly at the moment when you go to a webpage. This type of activity presents

Socket called client Socket. A client is an application which connects to the remote system to obtain the

desired data.

The other type is called server Socket. A server is a system which uses about socket to get authorized by

the application. It is the opposite of Client. So www.google.com is the server and the browser is the

client. Or in a more technical www.google.com is a HTTP server and the browser is the client HTTP

Now is the time to do some tasks using socket server. But before we go any further with some subjects

are affected in cases where you will be.

Displays the IP address of a given host

When you connect to a remote host, it is necessary to have its IP address.

#include<stdio.h> //printf

#include<string.h> //strcpy

#include<sys/socket.h>

#include<netdb.h> //hostent

#include<arpa/inet.h>

int main(int argc , char *argv[])

{

char *hostname = "www.google.com";

When you connect to a remote host, it is necessary to have its IP address. The function gethostbyname

() is used for this purpose.This function takes the domain name as a parameter and returns the goads

type structure. This structure IP.Kjo structure information included in library <netdb.h>.Let us take a

look at this structure. h_addr_list no ip addresses. So we now have some codes that you use these.

char ip[100];

struct hostent *he;

P a g e | 11

struct in_addr **addr_list;

int i;

if ( (he = gethostbyname( hostname ) ) == NULL)

{

//gethostbyname deshtuesi

herror("gethostbyname");

return 1;

}

//Hedh h_addr_list ne in_addr , qe kur h_addr_list ka gjithashtu

Adresat ip ne format te gjate.

addr_list = (struct in_addr **) he->h_addr_list;

for(i = 0; addr_list[i] != NULL; i++)

{

//Kthe te parin

strcpy(ip , inet_ntoa(*addr_list[i]) );

}

printf("%s u shpetua ne IP : %s" , hostname , ip);

return 0;

}

Output of the code would look like :

www.google.com resolved to : 74.125.235.20

So the above code is used to find the IP address of a given domain. IP addresses can then be used to

perform the connection to a Socket I set.

Inet_ntoa function () will convert the IP address in the format long format with the item. This is the

opposite of inet_addr ().

P a g e | 12

The longest we have seen significant structures which are used. Let we see the following:

1. sockaddr_in - Information linkage. Were using the function connect (), send (), recv ().

2. in_addr - IP Address long form.

3. sockaddr

4. goads - IP address of a host. I used by gethostbyname.

In the later part we will see how to create using socket. Servers are opposite the client, instead of

this being connected with others, they wait for incoming connections

Servers Socket

Ok we are now things of the servers. Socket servers operate in a different way.

Create a Server

Relationship of a address (and port).

Listening for incoming connections.

The acceptance of connections

Read / Submit

We have learned how to open and to learn a Socket also to close it. So we must make the

connection with convinces function ().

Connecting socket to a port

Function convince () can be used to connect to a Soken in an "address and port" combination. This

should sockaddr_in structure with function connect ().

P a g e | 13

int socket_desc;

struct sockaddr_in server;

// Creating Socket

socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)

{

printf("Socket can not be created ");

}

// Prepares sockaddr_in structure

server.sin_family = AF_INET;

server.sin_addr.s_addr = INADDR_ANY;

server.sin_port = htons( 8888 );

//Lidhja

if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)

{

puts("connection Problem ");

}

puts("Connection top ");

Now that the connection is done, it is time to do socket to listen incoming connections

(connections).

We connect the socket to an IP address and a specific port. By doing this we ensure that all the data

that are coming to head in this port being accepted by the relevant application to perform this

action.

This makes it clear that 2 socket cannot relate to the same port.

Listen for incoming connections in Socket

After connecting to a Socket in a port, next thing you should do is to listen for connections .For this

we need to use the socket in the way of listening. The function list () is used to insert socket in the

way listeners. Just add rows below after entering:

P a g e | 14

1 // Listen

2 listen (socket_desc, 3);

That is all. Now we come to the main part of accepting new connections.

Accept Connections

#include<stdio.h>

#include<sys/socket.h>

#include<arpa/inet.h> //inet_addr

int main(int argc , char *argv[])

{

int socket_desc , new_socket , c;

struct sockaddr_in server , client;

//Lidhja e soketit

socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)

{

printf("Socket can not be created ");

}

// Prepares sockaddr_in structure

server.sin_family = AF_INET;

server.sin_addr.s_addr = INADDR_ANY;

server.sin_port = htons( 8888 );

// Relationship or Convict, blindness

if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)

{

puts("connection Problem ");

}

puts("Lidhja u krye");

//Degjo

listen(socket_desc , 3);

// Acceptance of incoming connections

puts("Waiting for connections...");

c = sizeof(struct sockaddr_in);

new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);

if (new_socket<0)

{

perror("connection failed ");

}

puts("Binding was applied ");

return 0;

P a g e | 15

}

Accept function () is used to accept incoming connections.

Production of the Program

The launch of the program. This should be shown as follows.

Binding was applied

Waiting for incoming connections. . .

So far the program is waiting for incoming connections on port 8888. Do not close the program,

keep the charge. Now the client can be connected in this Socket at the port specified. Will need to

use telnet client to test this. Open Terminal and type

Terminal you should receive

And the server will show

Binding was applied

Waiting for incoming connections ...

Connection charge.

So we can now see that the client is connected to the server. Try the above process until you become

more perfect.

Get the IP address and connect with the client

You can get the IP address of a client in a connection from the port using sockaddr_in structure followed

by the function Accept (). Is very simple:

P a g e | 16

1char * client_ip = inet_ntoa (client.sin_addr);

2int client_port = ntohs (client.sin_port);

We accepted an incoming connection but were closed immediately. This is not productive. There are

many different things that can happen from that when the network connection is established. Although

the link is established for the purpose of communication. So let us return one client response:

In more simplicity can use the function write () to write something in a Socket for incoming connections

and the client will see it. Here is an example:

#include<stdio.h>

#include<string.h> //strlen

#include<sys/socket.h>

#include<arpa/inet.h> //inet_addr

#include<unistd.h> //write

int main(int argc , char *argv[])

{

int socket_desc , new_socket , c;

struct sockaddr_in server , client;

char *message;

// Creating socket

socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)

{

printf("Socket can not be created ");

}

// Prepares sockaddr_in structure

server.sin_family = AF_INET;

server.sin_addr.s_addr = INADDR_ANY;

server.sin_port = htons( 8888 );

// connection

if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)

{

puts("connection Problem ");

return 1;

}

P a g e | 17

puts("Connection top ");

// Listen

listen(socket_desc , 3);

// Accept incoming connections

puts("Waiting for incoming connections...");

c = sizeof(struct sockaddr_in);

new_socket = accept(socket_desc, (struct sockaddr *)&client,

(socklen_t*)&c);

if (new_socket<0)

{

perror("Application failed ");

return 1;

}

puts("Binding was applied ");

// Responding to the operating client

message = "Hello Client\n";

write(new_socket , message , strlen(message));

return 0;

}

Start the above code in a terminal. And then connect the kte server using telnet client from another

terminal and you should see.

So the client (telnet) received a reply from the server.

We can see that the connection was closed immediately after this message because the server is closed

after accepts and sends the message.

A server as www.google.com is always open for incoming connections

P a g e | 18

So we mean that the server is assumed to continue at all times relevant to the Internet. So we have to

keep our server open non-stop.

The simplest way to do this is to introduce Accept function () in a loop that so he can receive replies to

incoming connections in real-time.

Live Server

Thus a Live Server should always remain so. Let's see the code below:

#include<stdio.h>

#include<string.h> //strlen

#include<sys/socket.h>

#include<arpa/inet.h> //inet_addr

#include<unistd.h> //write

int main(int argc , char *argv[])

{

int socket_desc , new_socket , c;

struct sockaddr_in server , client;

char *message;

// Creating socket

socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)

{

printf("Socket can not be created ");

}

// Prepares sockaddr_in structure

server.sin_family = AF_INET;

server.sin_addr.s_addr = INADDR_ANY;

server.sin_port = htons( 8888 );

// hardening

if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)

{

puts("connection Problem ");

return 1;

}

puts("Connection top ");

// Listen

listen(socket_desc , 3);

// Application of incoming connections

puts("Waiting for incoming connections...");

P a g e | 19

c = sizeof(struct sockaddr_in);

while( (new_socket = accept(socket_desc, (struct sockaddr *)&client,(socklen_t*)&c)))

{

puts("Relationship accepted ");

// Customer response

message = "Hello Client \n";

write(new_socket , message , strlen(message));

}

if (new_socket<0)

{

perror("Application failed ");

return 1;

}

return 0;

}

Now start the program in terminal 1 and terminal 3 different step. From each of these three terminals

connect to the server on port specified.

Each terminal should be shown as follows:

The server should be shown:

Connection charge.

Waiting for connection...

Binding was applied

Binding was applied

P a g e | 20

Binding was applied

So now the server is going nonstop and telnet client terminals are also connected nonstop. All terminals

with telnet will display "Connection closed by foreign host."

Much better so far. But still there is effective communication between server and client.

The server accepts connections in a loop and then sends them a message, and then he does nothing

with them. Also he is not able to hold more than one connection per time.

So now is the time to create a server that can hold more relationships at the same time.

Keeping more connections to the server with "threads"

To keep any links to share the code to act for the main server time accepting any authorized connection.

One way is by keeping them using themes or "threads". The main server receives connections and

creates a new topic to maintain communication for connecting fixed and then turn the server to accept

new connections

Linux threads library can be performed with pthread (POSIX threads). It will be good if we read for this

tutorial small library if you do not know anything about them.

However, use is not very complicated

#include<stdio.h>

#include<string.h> //strlen

#include<stdlib.h> //strlen

#include<sys/socket.h>

#include<arpa/inet.h> //inet_addr

#include<unistd.h> //write

#include<pthread.h> //for threading , link with lpthread

void *connection_handler(void *);

int main(int argc , char *argv[])

{

int socket_desc , new_socket , c , *new_sock;

struct sockaddr_in server , client;

char *message;

// Creating socket

socket_desc = socket(AF_INET , SOCK_STREAM , 0);

if (socket_desc == -1)

{

printf("Socket can not be created ");

P a g e | 21

}

// Preparation of the structure sockaddr_in

server.sin_family = AF_INET;

server.sin_addr.s_addr = INADDR_ANY;

server.sin_port = htons( 8888 );

// Relationship or blindness

if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)

{

puts("connection Problem ");

return 1;

}

puts("Connection top ");

// Listen

listen(socket_desc , 3);

// Acceptance of incoming connections

puts("Waiting for connections...");

c = sizeof(struct sockaddr_in);

while( (new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)))

{

puts("Relationship accepted ");

// Sending a message to the client

message = "Hello Client\n";

write(new_socket , message , strlen(message));

pthread_t sniffer_thread;

new_sock = malloc(1);

*new_sock = new_socket;

if( pthread_create( &sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0)

{

perror("can not create topic ");

return 1;

}

//pthread_join( sniffer_thread , NULL);

puts("The holder was appointed ");

}

if (new_socket<0)

{

perror("Application failed ");

return 1;

}

P a g e | 22

return 0;

}

/*

This will keep connections for each customer connected

*/

void *connection_handler(void *socket_desc)

{

// Get the description of the socket

int sock = *(int*)socket_desc;

char *message;

//Send messages to clienti

message = " Hello, I'm your retainer connections \n";

write(sock , message , strlen(message));

message = " It is my duty to communicate the with you ";

write(sock , message , strlen(message));

//point socket

free(socket_desc);

return 0;

}

Start the server with up and step 3 terminal as before. Now the server will create themes for each

customer that will be connected to the

Terminals with telnet will display.

It looks very good, but the holder of communication is also a bit lazy. After greeting he closes the

program. He must stay alive and to communicate with the client. One way is to keep the connection

made to wait for some messages from the client for as long it is associated. If the client's bolts, holder of

the links must be completed.

P a g e | 23

So linkage holder can reset as follows: Now we need to use threads to create the means for each

connection that the server will accept. The example below I coded in C language for the creation of the

server with the following topics:

/*

This will keep for each client connection

*/

void *connection_handler(void *socket_desc)

{

// Get the description of the socket

int sock = *(int*)socket_desc;

int read_size;

char *message , client_message[2000];

// Send message to the client

message = " Hello, I'm your retainer connections\n";

write(sock , message , strlen(message));

message = " Now press and something should turn back to you \n”;

write(sock , message , strlen(message));

// Receives a message from client

while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )

{

// Send message back to the client

write(sock , client_message , strlen(client_message));

}

if(read_size == 0)

{

puts("Client timed out ");

fflush(stdout);

}

else if(read_size == -1)

{

perror("marking failed");

}

//pointer socket

free(socket_desc);

return 0;

}

P a g e | 24

Holder above link will take some data from the client and will return it back to the same. Simple! .now

given below production of code

$ Telnet localhost 8888

Trying 127.0.0.1...

Connected to localhost.

Escape character is '^]'.

Hello Client

Hello, I'm your retainer connections

Now press something should turn back to you Hello

Hello

How are you

How are you

i am very well

i am very well

Relationship with pthread library

When compile programs that use pthread library we should link with this library. Below is given the way

he can perform the connection.

$ gcc program.c -lpthread

Conclusion

By now you should have learned the simple things in socket programming in C. You may try to do several

experiments like to write a program that acts as a chat or something similar to this.

Thank you