Você está na página 1de 25

Socket

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

Page |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*/
};

Page |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.

Page |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.

Page |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.

Page |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.

Page |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;
}

Page |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");

Page |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

Page |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

Você também pode gostar