of 19
8/13/2019 Socket Programing Example
1/19
TCP/IP socket programming in CThis is a quick tutorial on socket programming in clanguage on a Linux system.
"Linux" because the code snippets shown oer here will work only on a Linux
system and not on !indows. The windows api to socket programmingis called
winsock and we shall go through it in another tutorial.
ockets are the "irtual" endpoints o#
any kind o# network communications
done between $ hosts oer in a
network. %or example when you type
www.google.com in your web
browser& it opens a socket and
connects to google.com to #etch the
page and show it to you. ame with
any chat client like gtalk or skype.
'ny network communication goes
through a socket.
The socket api on linux is similar to
bsd/unix sockets #rom which it has
eoled. 'lthough oer time the api has become slightly di##erent at #ew places.
'nd now the newer o##icial standard is posix sockets apiwhich is same as bsd
sockets.
This tutorial assumes that you hae basic knowledge o# C and pointers. (ou willneed to hae gcc compilerinstalled on your Linux system. 'n I)* along with
gcc would be great. I would recommend geany as you can quickly edit and run
single #ile programs in it without much con#igurations. +n ubuntu you can do a
sudo apt,get install geany on the terminal.
'll along the tutorial there are code snippets to demonstrate some concepts. (ou
can run those code snippets in geany rightaway and test the results to better
understand the concepts.
Create a socketThis #irst thing to do is create a socket. The socket#unction does this.
-ere is a code sample 1234567
8910
#include#include
tmain(intargc , char*argv[]){ tsocket_desc; socket_desc socket!"_$%&' ( )*+,_)'-&" ( 0
1(socket_desc == -1) {
http://www.binarytides.com/winsock-socket-programming-tutorial/http://en.wikipedia.org/wiki/POSIXhttp://en.wikipedia.org/wiki/POSIXhttp://www.binarytides.com/winsock-socket-programming-tutorial/8/13/2019 Socket Programing Example
2/19
1112131415
23 t1("Could not create socket"); 3etu3 0;
%unction socket0 creates a socket and returns a descriptor which can be used in
other #unctions. The aboe code will create a socket with #ollowing properties
'ddress %amily , '%1I2*T this is IP ersion 30Type , +C41T5*'6 this means connection oriented TCP protocol0Protocol , 7 8 or IPP5+T+1IP This is IP protocol9
2ext we shall try to connect to some serer using this socket.
!e can connect to www.google.com
Note
'part #rom +C41T5*'6 type o# sockets there is another type called
+C41):5'6 which indicates the UDP protocol. This type o# socket is non,connection socket. In this tutorial we shall stick to +C41T5*'6 or TCP sockets.
Connect socket to a server
!e connect to a remote serer on a certain port number. o we need $ things& ip
addressand port numberto connect to.
To connect to a remote serer we need to do a couple o# things. %irst is to create a
sockaddr1in structure with proper alues.
struct sockaddr1in serer;
-ae a look at the structure
12345678
910111213141516
// $4 "_$%&' socketsst3uctsockaddr_in sho3t sin_!amil; ## e$g$ %&_', %&_'+ unsined short sin_ort; ## e$g$ tons(./0) st3uctin_addr sin_addr; ## see struct in_addr, elo2 ch93 sin_3ero[4]; ## 3ero tis i! ou 2ant tost3uctin_addr unsined longs_addr; ## load 2it inet_ton()st3uctsockaddr unsined short sa_!amil; ## address !amil, %&_555 ch93 sa_data[1/]; ## 1/ tes o! rotocoladdress
The sockaddr1in has a member called sin1addr o# type in1addr which has a s1addr
which is nothing but a long. It contains the IP address in long #ormat.%unction inet_addris a ery handy #unction to conert an IP address to a long
#ormat. This is how you do it
8/13/2019 Socket Programing Example
3/19
1see.sin_dd.s_dd inet_dd!"6/$178$7.8$70");
o you need to know the IP address o# the remote serer you are connecting to.
-ere we used the ip address o# google.com as a sample. ' little later on we shall
see how to #ind out the ip address o# a gien domain name.
The last thing needed is the connect#unction. It needs a socket and a sockaddr
structure to connect to. -ere is a code sample.
123456789
10111213141516171819
2021222324252627282930
#include#include#include //inet_dd tmain(intargc , char*argv[]){ tsocket_desc; st3uctsockaddr_in server;
//+ete socket socket_desc socket!"_$%&' ( )*+,_)'-&" ( 0 1(socket_desc == -1) { 23 t1("Could not create socket");
see.sin_dd.s_dd inet_dd!"6/$178$7.8$70"); see.sin_:ily "_$%&' see.sin_ot htons! 80
//+onnect to e:ote see 1(connect(socket_desc , (structsockaddr *)9server ,sizeof(server)) : 0) { 2uts("connect error"); 3etu3 1; 2uts("Connected"); 3etu3 0;
It cannot be any simpler. It creates a socket and then connects. I# you run the
program it should show Connected.
Try connecting to a port di##erent #rom port
8/13/2019 Socket Programing Example
4/19
streams each haing communication o# its own. Think o# this as a pipe which is not
inter#ered by other data.
+ther sockets like =)P & IC6P & '5P dont hae a concept o# "connection". These
are non,connection based communication. !hich means you keep sending or
receiing packets #rom anybody and eerybody.
Send data over socket
%unction sendwill simply send data. It needs the socket descriptor & the data to
send and its si>e.
-ere is a ery simple example o# sending some data to google.com ip 1234
567891011121314
1516171819202122232425
2627282930313233343536373839
#include#include //stlen#include#include //inet_dd
tmain(intargc , char*argv[]){ tsocket_desc; st3uctsockaddr_in server; ch93*message;
//+ete socket socket_desc socket!"_$%&' ( )*+,_)'-&" ( 0 1(socket_desc == -1) { 23 t1("Could not create socket");
see.sin_dd.s_dd inet_dd!"6/$178$7.8$70"); see.sin_:ily "_$%&' see.sin_ot htons! 80
//+onnect to e:ote see 1(connect(socket_desc , (structsockaddr *)9server ,sizeof(server)) : 0)
{ 2uts("connect error"); 3etu3 1; 2uts("Connectedn");
//)end so:e dt :esse "#1$1rnrn"; 1( send(socket_desc , message , strlen(message) , 0) : 0) { 2uts("?end !ailed"); 3etu3 1;
8/13/2019 Socket Programing Example
5/19
404142
2uts("@ata ?endn"); 3etu3 0;
In the aboe example & we #irst connect to an ip address and then send the string
message ":*T / -TTP/?.?@r@n@r@n" to it.
The message is actually a http command to #etch the mainpage o# a website.
2ow that we hae send some data & its time to receie a reply #rom the serer. o
lets do it.
Note
!hen sending data to a socket you are basically writing data to that socket. This is
similar to writing data to a #ile. -ence you can also use the 2rite#unction to send
data to a socket. Later in this tutorial we shall use write #unction to send data.
Receive data on socket%unction recvis used to receie data on a socket. In the #ollowing example we
shall send the same message as the last example and receie a reply #rom the
serer.12345678910111213141516
1718192021222324252627
282930
#include#include //stlen#include#include //inet_dd tmain(intargc , char*argv[]){ tsocket_desc; st3uctsockaddr_in server; ch93*message , server_rel[7000];
//+ete socket socket_desc socket!"_$%&' ( )*+,_)'-&" ( 0 1(socket_desc == -1) { 23 t1("Could not create socket");
see.sin_dd.s_dd inet_dd!"6/$178$7.8$70"); see.sin_:ily "_$%&' see.sin_ot htons! 80
//+onnect to e:ote see 1(connect(socket_desc , (structsockaddr *)9server ,sizeof(server)) : 0) { 2uts("connect error"); 3etu3 1;
8/13/2019 Socket Programing Example
6/19
31323334353637383940414243444546
47484950
2uts("Connectedn");
//)end so:e dt :esse "#1$1rnrn"; 1( send(socket_desc , message , strlen(message) , 0) : 0) {
2uts("?end !ailed"); 3etu3 1; 2uts("@ata ?endn");
//-eceie ely o: the see 1( recv(socket_desc, server_rel , 7000 , 0) : 0) { 2uts("recv !ailed"); 2uts("Ael receivedn"); 2uts(server_rel); 3etu3 0;
-ere is the output o# the aboe code
+onnected
;t )end
-ely eceied
''/1.1 302 ound
=oction htt//.oole.co.in/
+che?+ontol ite
+ontent?'ye te@t/ht:l chsetA'?8
)et?+ookie-&$;0edd21160dB2190'1324644706=1324644706)C6h;+9cDE&o_o e@ies)un( 22?;ec?2013 125146 E' th/ do:in.oole.co:
;te i( 23 ;ec 2011 125146 E'
)ee s
+ontent?=enth 221
F?F))?otection 1 :odeBlock
F?:e?*tions )"&*-$E$%
8/13/2019 Socket Programing Example
7/19
.
8/13/2019 Socket Programing Example
8/19
3456789
{ ch93*_name; #* B!!icial name o! ost$ *# ch93**_aliases; #* %lias list$ *# t_addrte; #* ost address te$ *# t_lengt; #* engt o! address$ *# ch93**_addr_list; #* ist o! addresses !rom nameserver$ *#
The _addr_listhas the IP addresses. o now lets hae some code to use them.
1234567
8910111213141516171819202122232425262728
2930313233
#include //int#include //stcy#include#include //hostent#include tmain(intargc , char*argv[]){ ch93*ostname = "222$google$com"; ch93i[100]; st3uctostent *e; st3uctin_addr **addr_list; ti; 1( (e = getostname( ostname ) ) == D)
{ //ethostByn:e iled heo!"getostname");
3etu3 1;
//+st the h_dd_list to in_dd ( since h_dd_list lsohs the i ddess in lon o:t only dd_list !structin_addr **) e-E_addr_list; 1o3(i = 0; addr_list[i] F= D; iGG)
{ //-etun the ist one st3c2y(i , inet_ntoa(*addr_list[i]) ); 23 t1("Hs resolved to I Hs", ostname , i); 3etu3 0;
+utput o# the code would look like
.oole.co: esoled to 74.125.235.20
o the aboe code can be used to #ind the ip address o# any domain name. Then
the ip address can be used to make a connection using a socket.
%unction inet_ntoawill conert an IP address in long #ormat to dotted #ormat. This
is Dust the opposite o# inet_addr.
8/13/2019 Socket Programing Example
9/19
o #ar we hae see some important structures that are used. Lets reise them
?. sockaddr_in, Connection in#ormation. =sed by connect & send & rec etc.
$. in_addr, Ip address in long #ormat
. sockaddr
3. ostent, The ip addresses o# a hostname. =sed by gethostbyname
In the next part we shall look into creating serers using socket. erers are the
opposite o# clients& that instead o# connecting out to others& they wait #or incoming
connections.
ocket serer+4 now onto serer things. ocket serers operate in the #ollowing manner
?. +pen a socket$. Eind to a addressand port0.
. Listen #or incoming connections.3. 'ccept connectionsF. 5ead/end
!e hae already learnt how to open a socket. o the next thing would be to bind it.
!ind socket to a port
The bind #unction can be used to bind a socket to a particular "address and port"
combination. It needs a sockaddr1in structure similar to connect #unction.
12345678910
1112131415161718192021
tsocket_desc;st3uctsockaddr_in server;//+ete socketsocket_desc socket!"_$%&' ( )*+,_)'-&" ( 01(socket_desc == -1){ 23 t1("Could not create socket");//ee the sockdd_in stuctue
see.sin_:ily "_$%&'see.sin_dd.s_dd $%";;-_"%Jsee.sin_ot htons! 8888 //Iind1( ind(socket_desc,(structsockaddr *)9server ,sizeof(server)) : 0){ 2uts("ind !ailed");
2uts("ind done");2ow that bind is done& its time to make the socket listen to connections. !e bind asocket to a particular IP address and a certain port number. Ey doing this we
8/13/2019 Socket Programing Example
10/19
ensure that all incoming data which is directed towards this port number is
receied by this application.
This makes it obious that you cannot hae $ sockets bound to the same port.
Listen for incoming connections on te socket
'#ter binding a socket to a port the next thing we need to do is listen #or
connections. %or this we need to put the socket in listening mode.
%unction listenis used to put the socket in listening mode. Gust add the #ollowing
line a#ter bind.12//=istenlisten!socket_desc ( 3
Thats all. 2ow comes the main part o# accepting new connections.
"ccept connection%unction accetis used #or this. -ere is the code12345678
910111213141516171819
20212223242526272829
303132
#include#include#include //inet_dd tmain(intargc , char*argv[]){ tsocket_desc , ne2_socket , c; st3uctsockaddr_in server , client;
//+ete socket socket_desc socket!"_$%&' ( )*+,_)'-&" ( 0 1(socket_desc == -1) { 23 t1("Could not create socket");
//ee the sockdd_in stuctue see.sin_:ily "_$%&' see.sin_dd.s_dd $%";;-_"%J
see.sin_ot htons! 8888
//Iind 1( ind(socket_desc,(structsockaddr *)9server ,sizeof(server)) : 0) { 2uts("ind !ailed"); 2uts("ind done");
//=isten listen!socket_desc ( 3
8/13/2019 Socket Programing Example
11/19
3334353637
38394041424344
//"ccet nd inco:in connection 2uts("Jaiting !or incoming connections$$$"); c sizeof(structsockaddr_in); ne_socket ccet!socket_desc( !structsockaddr *)9client,(socklen_t*)9c); 1(ne2_socket:0) { 2e33o3("accet !ailed"); 2uts("Connection acceted"); 3etu3 0;
Program output
5un the program. It should show
Bind done
Litin o inco:in connections...
o now this program is waiting #or incoming connections on port
8/13/2019 Socket Programing Example
12/19
!e can simply use the 2rite#unction to write something to the socket o# the
incoming connection and the client should see it. -ere is an example 1234567891011121314
1516171819202122232425
262728293031323334353637383940414243444546
474849
#include#include //stlen#include#include //inet_dd#include //ite tmain(intargc , char*argv[]){ tsocket_desc , ne2_socket , c; st3uctsockaddr_in server , client; ch93*message;
//+ete socket socket_desc socket!"_$%&' ( )*+,_)'-&" ( 0
1(socket_desc == -1) { 23 t1("Could not create socket");
//ee the sockdd_in stuctue see.sin_:ily "_$%&' see.sin_dd.s_dd $%";;-_"%J see.sin_ot htons! 8888
//Iind
1( ind(socket_desc,(structsockaddr *)9server ,sizeof(server)) : 0) { 2uts("ind !ailed"); 3etu3 1; 2uts("ind done");
//=isten listen!socket_desc ( 3
//"ccet nd inco:in connection 2uts("Jaiting !or incoming connections$$$"); c sizeof(structsockaddr_in); ne_socket ccet!socket_desc( !structsockaddr *)9client,(socklen_t*)9c); 1(ne2_socket:0) { 2e33o3("accet !ailed"); 3etu3 1;
2uts("Connection acceted");
8/13/2019 Socket Programing Example
13/19
50515253
//-ely to the client :esse "ello Client , ' ave received our connection$Kut ' ave to go no2, en"; ite!ne_socket ( :esse ( strlen(message)); 3etu3 0;
5un the aboe code in ? terminal. 'nd connect to this serer using telnet #rom
another terminal and you should see this
M telnet loclhost 8888
'yin 127.0.0.1...
+onnected to loclhost.
&sce chcte is NOPN.
ello +lient ( $ he eceied you connection. Iut $ he to o no( Bye
+onnection closed By oein host.o the clienttelnet0 receied a reply #rom serer.
!e can see that the connection is closed immediately a#ter that simply because
the serer program ends a#ter accepting and sending reply. ' serer like
www.google.com is always up to accept incoming connections.
It means that a serer is supposed to be running all the time. '#terall its a serer
meant to sere. o we need to keep our serer 5=22I2: non,stop. The simplest
way to do this is to put the accetin a loop so that it can receie incoming
connections all the time.
Live Server
o a lie serer will be alie #or all time. Lets code this up
123456
78910111213141516
171819
#include#include //stlen#include#include //inet_dd#include //ite tmain(intargc , char*argv[]){ tsocket_desc , ne2_socket , c; st3uctsockaddr_in server , client; ch93*message;
//+ete socket socket_desc socket!"_$%&' ( )*+,_)'-&" ( 0 1(socket_desc == -1) {
23 t1("Could not create socket");
8/13/2019 Socket Programing Example
14/19
202122232425262728293031323334
3536373839404142434445
46474849505152535455
//ee the sockdd_in stuctue see.sin_:ily "_$%&' see.sin_dd.s_dd $%";;-_"%J see.sin_ot htons! 8888
//Iind
1( ind(socket_desc,(structsockaddr *)9server ,sizeof(server)) : 0) { 2uts("ind !ailed"); 3etu3 1; 2uts("ind done");
//=isten listen!socket_desc ( 3
//"ccet nd inco:in connection 2uts("Jaiting !or incoming connections$$$"); c sizeof(structsockaddr_in); >h le( (ne2_socket = accet(socket_desc, (structsockaddr*)9client, (socklen_t*)9c)) ) { 2uts("Connection acceted");
//-ely to the client :esse "ello Client , ' ave received our
connection$ Kut ' ave to go no2, en"; ite!ne_socket ( :esse ( strlen(message)); 1(ne2_socket:0) { 2e33o3("accet !ailed"); 3etu3 1; 3etu3 0;
!e haent done a lot there. Gust the accept was put in a loop.
2ow run the program in ? terminal & and open other terminals. %rom each o# the
terminal do a telnet to the serer port.
*ach o# the telnet terminal would show
M telnet loclhost 8888
'yin 127.0.0.1...
+onnected to loclhost.
&sce chcte is NOPN.
ello +lient ( $ he eceied you connection. Iut $ he to o no( Bye
8/13/2019 Socket Programing Example
15/19
'nd the serer terminal would show
Bind done
Litin o inco:in connections...
+onnection cceted
+onnection cceted
+onnection cceted
o now the serer is running nonstop and the telnet terminals are also connected
nonstop. 2ow close the serer program.
'll telnet terminals would show "Connection closed by #oreign host."
:ood so #ar. Eut still there is not e##ectie communication between the serer and
the client.
The serer program accepts connections in a loop and Dust send them a reply& a#ter
that it does nothing with them. 'lso it is not able to handle more than ? connection
at a time. o now its time to handle the connections & and handle multiple
connections together.
#andle multiple socket connections $it treads
To handle eery connection we need a separate handling code to run along with
the main serer accepting connections.
+ne way to achiee this is using threads. The main serer program accepts a
connection and creates a new thread to handle communication #or the connection&
and then the serer goes back to accept more connections.
+n Linux threading can be done with the pthread posix threads0 library. It would
be good to read some small tutorial about it i# you dont know anything about it.
-oweer the usage is not ery complicated.
!e shall now use threads to create handlers #or each connection the serer
accepts. Lets do it pal.
12345678910111213
141516
#include#include //stlen#include //stlen#include#include //inet_dd#include //ite#include //o thedin ( link ith lthed6o d*connection_andler(void*); tmain(intargc , char*argv[]){
tsocket_desc , ne2_socket , c , *ne2_sock; st3uctsockaddr_in server , client; ch93*message;
8/13/2019 Socket Programing Example
16/19
171819202122
232425262728293031323334353637383940414243
4445464748495051525354
5556575859606162636465666768
//+ete socket
socket_desc socket!"_$%&' ( )*+,_)'-&" ( 0 1(socket_desc == -1) { 23 t1("Could not create socket");
//ee the sockdd_in stuctue see.sin_:ily "_$%&' see.sin_dd.s_dd $%";;-_"%J see.sin_ot htons! 8888
//Iind 1( ind(socket_desc,(structsockaddr *)9server ,sizeof(server)) : 0) { 2uts("ind !ailed"); 3etu3 1; 2uts("ind done");
//=isten listen!socket_desc ( 3
//"ccet nd inco:in connection 2uts("Jaiting !or incoming connections$$$"); c sizeof(structsockaddr_in); >h le( (ne2_socket = accet(socket_desc, (structsockaddr*)9client, (socklen_t*)9c)) ) { 2uts("Connection acceted");
//-ely to the client :esse "ello Client , ' ave received ourconnection$ %nd no2 ' 2ill assign a andler !or oun"; ite!ne_socket ( :esse ( strlen(message));
thed_t snie_thed ne_sock malloc(1); Kne_sock ne_socket 1( tread_create( 9sni!!er_tread , D ,connection_andler , (void*) ne2_sock) : 0) { 2e33o3("could not create tread"); 3etu3 1;
//%o Qoin the thed ( so tht e dont te:inte Beoethe thed //thed_Qoin! snie_thed ( %A==
8/13/2019 Socket Programing Example
17/19
6970717273747576777879808182
8384858687888990919293
94959697
2uts("andler assigned"); 1(ne2_socket:0) { 2e33o3("accet !ailed"); 3etu3 1; 3etu3 0;/KK 'his ill hndle connection o ech clientK K/6o d*connection_andler(void*socket_desc){ //Eet the socket descito tsock = *(int*)socket_desc; ch93*message;
//)end so:e :esses to the client :esse "
8/13/2019 Socket Programing Example
18/19
+ne way to do this is by making the connection handler wait #or some message
#rom a client as long as the client is connected. I# the client disconnects & the
connection handler ends.
o the connection handler can be rewritten like this
12345678910
111213141516171819202122232425262728293031
3233343536373839
/KK 'his ill hndle connection o ech clientK K/6o d*connection_andler(void*socket_desc){ //Eet the socket descito tsock = *(int*)socket_desc; tread_si3e; ch93*message , client_message[7000];
//)end so:e :esses to the client
:esse "
8/13/2019 Socket Programing Example
19/19
+onnected to loclhost.
&sce chcte is NOPN.
ello +lient ( $ he eceied you connection. "nd no $ ill ssin hndle o you
EeetinsR $ : you connection hndle
%o tye so:ethin nd i shll eet ht you tyeello
ello
o e you
o e you
$ : ine
$ : ine
o now we hae a serer thats communicatie. Thats use#ul now.
Linking te ptread library
!hen compiling programs that use the pthread library you need to link the library.
This is done like this
M cc o:.c ?lthed
Conclusion
Ey now you must hae learned the basics o# socket programming in C. (ou can
try out some experiments like writing a chat client or something similar.
I# you think that the tutorial needs some addons or improements or any o# thecode snippets aboe dont work then #eel #ree to make a comment below so that it
gets #ixed.