Socket Programming in C/C++
Socket Programming in C/C++
Socket Programming in C/C++
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
sockets<br />
<strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong><br />
c○Mani Radhakrishnan and Jon Solworth<br />
September 24, 2004<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Contact Info<br />
sockets<br />
Mani Radhakrishnan<br />
Office<br />
4224 SEL<br />
email<br />
mradhakr @ cs . uic . edu<br />
Office Hours<br />
Tuesday 1 - 4 PM<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Introduction<br />
sockets<br />
TCP<br />
UDP<br />
<strong>Socket</strong>s are a protocol <strong>in</strong>dependent method of creat<strong>in</strong>g a<br />
connection between processes. <strong>Socket</strong>s can be either<br />
◮ connection based or connectionless: Is a connection<br />
established before communication or does each packet<br />
describe the dest<strong>in</strong>ation?<br />
◮ packet based or streams based: Are there message boundaries<br />
or is it one stream?<br />
◮ reliable or unreliable. Can messages be lost, duplicated,<br />
reordered, or corrupted?<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
<strong>Socket</strong> characteristics<br />
sockets<br />
TCP<br />
UDP<br />
<strong>Socket</strong> are characterized by their doma<strong>in</strong>, type and transport<br />
protocol. Common doma<strong>in</strong>s are:<br />
◮ AF UNIX: address format is UNIX pathname<br />
◮ AF INET: address format is host and port number<br />
Common types are:<br />
virtual circuit: received <strong>in</strong> order transmitted and reliably<br />
datagram: arbitrary order, unreliable<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockets<br />
<strong>Socket</strong> characteristics (cont’d)<br />
TCP<br />
UDP<br />
Each socket type has one or more protocols. Ex:<br />
◮ TCP/IP (virtual circuits)<br />
◮ UDP (datagram)<br />
Use of sockets:<br />
◮ Connection–based sockets communicate client-server: the<br />
server waits for a connection from the client<br />
◮ Connectionless sockets are peer-to-peer: each process is<br />
symmetric.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
<strong>Socket</strong> APIs<br />
sockets<br />
TCP<br />
UDP<br />
◮ socket: creates a socket of a given doma<strong>in</strong>, type, protocol<br />
(buy a phone)<br />
◮ b<strong>in</strong>d: assigns a name to the socket (get a telephone number)<br />
◮ listen: specifies the number of pend<strong>in</strong>g connections that<br />
can be queued for a server socket. (call wait<strong>in</strong>g allowance)<br />
◮ accept: server accepts a connection request from a client<br />
(answer phone)<br />
◮ connect: client requests a connection request to a server<br />
(call)<br />
◮ send, sendto: write to connection (speak)<br />
◮ recv, recvfrom: read from connection (listen)<br />
◮ shutdown: end the call<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockets<br />
TCP<br />
UDP<br />
Connection-based communication<br />
Server performs the follow<strong>in</strong>g actions<br />
◮ socket: create the socket<br />
◮ b<strong>in</strong>d: give the address of the socket on the server<br />
◮ listen: specifies the maximum number of connection<br />
requests that can be pend<strong>in</strong>g for this process<br />
◮ accept: establish the connection with a specific client<br />
◮ send,recv: stream-based equivalents of read and write<br />
(repeated)<br />
◮ shutdown: end read<strong>in</strong>g or writ<strong>in</strong>g<br />
◮ close: release kernel data structures<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
TCP client<br />
sockets<br />
Client performs the follow<strong>in</strong>g actions<br />
◮ socket: create the socket<br />
◮ connect: connect to a server<br />
◮ send,recv: (repeated)<br />
◮ shutdown<br />
◮ close<br />
TCP<br />
UDP<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
TCP-based sockets<br />
b<strong>in</strong>d<br />
listen<br />
sockets<br />
accept close<br />
send/recv<br />
shutdown<br />
close<br />
TCP<br />
UDP<br />
server client<br />
socket<br />
socket<br />
connect<br />
send/recv<br />
shutdown<br />
close<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
socket API<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
sockets<br />
TCP<br />
UDP<br />
4 i n t s o c k e t ( i n t doma<strong>in</strong> , i n t type , i n t p r o t o c o l ) ;<br />
Returns a file descriptor (called a socket ID) if successful, -1<br />
otherwise. Note that the socket returns a socket descriptor which<br />
is the same as a file descriptor.<br />
The doma<strong>in</strong> is AF INET.<br />
The type argument can be:<br />
◮ SOCK STREAM: Establishes a virtual circuit for stream<br />
◮ SOCK DGRAM: Establishes a datagram for communication<br />
◮ SOCK SEQPACKET: Establishes a reliable, connection based,<br />
two way communication with maximum message size. (This is<br />
not available on most mach<strong>in</strong>es.)<br />
protocol is usually zero, so that type def<strong>in</strong>es the connection<br />
with<strong>in</strong> doma<strong>in</strong>.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
<strong>in</strong>d<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
sockets<br />
TCP<br />
UDP<br />
4 i n t b i n d ( i n t s i d , s t r u c t s o c k a d d r ∗addrPtr , i n t l e n )<br />
Where<br />
◮ sid: is the socket id<br />
◮ addrPtr: is a po<strong>in</strong>ter to the address family dependent<br />
address structure<br />
◮ len: is the size of *addrPtr<br />
Associates a socket id with an address to which other processes<br />
can connect. In <strong>in</strong>ternet protocol the address is [ipNumber,<br />
portNumber]<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockaddr<br />
For the <strong>in</strong>ternet family:<br />
sockets<br />
TCP<br />
UDP<br />
s t r u c t s o c k a d d r i n {<br />
2 s a f a m i l y t s i n f a m i l y ; // = AF INET<br />
i n p o r t t s i n p o r t ; // i s a p o r t number<br />
4 s t r u c t i n a d d r s i n a d d r ; // an IP a d d r e s s<br />
}<br />
For unix sockets (only works between processes on the same<br />
mach<strong>in</strong>e)<br />
s t r u c t s o c k a d d r u n {<br />
2 u i n t 8 t s u n l e n g t h ; //<br />
s h o r t s u n f a m i l y ; // = AF LOCAL<br />
4 char s u n p a t h [ 1 0 0 ] ; // n u l l t e r m i n a t e d pathname<br />
// (100 i s p o s i x 1 . g m<strong>in</strong>imum )<br />
6 }<br />
When us<strong>in</strong>g <strong>in</strong>ternet sockets, the second parameter of b<strong>in</strong>d (of<br />
type sockaddr <strong>in</strong> *) must be cast to (sockaddr *).<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
listen<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
4 i n t l i s t e n ( i n t s i d , i n t s i z e ) ;<br />
sockets<br />
TCP<br />
UDP<br />
Where size it the number of pend<strong>in</strong>g connection requests allowed<br />
(typically limited by Unix kernels to 5).<br />
Returns the 0 on success, or -1 if failure.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
accept<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
sockets<br />
TCP<br />
UDP<br />
4 i n t a c c e p t ( i n t s i d , s t r u c t s o c k a d d r ∗addrPtr , i n t ∗ l e n P t r )<br />
Returns the socketId and address of client connect<strong>in</strong>g to socket.<br />
if lenPtr or addrPtr equal zero, no address structure is returned.<br />
lenPtr is the maximum size of address structure that can be<br />
called, returns the actual value.<br />
Waits for an <strong>in</strong>com<strong>in</strong>g request, and when received creates a socket<br />
for it.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
accept styles<br />
sockets<br />
TCP<br />
UDP<br />
There are basically three styles of us<strong>in</strong>g accept:<br />
Iterat<strong>in</strong>g server: Only one socket is opened at a time. When the<br />
process<strong>in</strong>g on that connection is completed, the<br />
socket is closed, and next connection can be<br />
accepted.<br />
Fork<strong>in</strong>g server: After an accept, a child process is forked off to<br />
handle the connection. Variation: the child processes<br />
are preforked and are passed the socketId.<br />
Concurrent s<strong>in</strong>gle server: use select to simultaneously wait on all<br />
open socketIds, and wak<strong>in</strong>g up the process only when<br />
new data arrives.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockets<br />
Pro and Con of Accept styles<br />
TCP<br />
UDP<br />
◮ Iterat<strong>in</strong>g server is basically a low performance technique s<strong>in</strong>ce<br />
only one connection is open at a time.<br />
◮ Fork<strong>in</strong>g servers enable us<strong>in</strong>g multiple processors. But they<br />
make shar<strong>in</strong>g state difficult, unless performed with threads.<br />
Threads, however present a very fragile programm<strong>in</strong>g<br />
environment.<br />
◮ Concurrent s<strong>in</strong>gle server: reduces context switches relative to<br />
fork<strong>in</strong>g processes and complexity relative to threads. But does<br />
not benefit from multiprocessors.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
send<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
sockets<br />
4 i n t send ( i n t s i d , c o n s t char ∗ b u f f e r P t r ,<br />
i n t l e n , i n t f l a g )<br />
TCP<br />
UDP<br />
Send a message. Returns the number of bytes sent or -1 if failure.<br />
(Must be a bound socket).<br />
flag is either<br />
◮ 0: default<br />
◮ MSG OOB: Out-of-band high priority communication<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
ecv<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
4 i n t r e c v ( i n t s i d , char ∗ b u f f e r P t r ,<br />
i n t l e n , i n t f l a g s )<br />
sockets<br />
TCP<br />
UDP<br />
Receive up to len bytes <strong>in</strong> bufferPtr. Returns the number of<br />
bytes received or -1 on failure.<br />
flags can be either<br />
◮ 0: default<br />
◮ MSG OOB: out-of-bound message<br />
◮ MSG PEEK: look at message without remov<strong>in</strong>g<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
shutdown<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
4 i n t shutdown ( i n t s i d , i n t how )<br />
sockets<br />
TCP<br />
UDP<br />
Disables send<strong>in</strong>g (how=1 or how=2) or receiv<strong>in</strong>g (how=0 or<br />
how=2). Returns -1 on failure.<br />
acts as a partial close.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
connect<br />
sockets<br />
this is the first of the client calls<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
TCP<br />
UDP<br />
4 i n t c o n n e c t ( i n t s i d , s t r u c t s o c k a d d r ∗addrPtr , i n t l e n )<br />
Specifies the dest<strong>in</strong>ation to form a connection with (addrPtr), and<br />
returns a 0 if successful, -1 otherwise.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Denot<strong>in</strong>g Connections<br />
sockets<br />
TCP<br />
UDP<br />
Note that a connection is denoted by a 5-tuple:<br />
◮ from IP<br />
◮ from port<br />
◮ protocol<br />
◮ to IP<br />
◮ to port<br />
So that multiple connections can share the same IP and port.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Port usage<br />
sockets<br />
TCP<br />
UDP<br />
Note that the <strong>in</strong>itiator of communications needs a fixed port to<br />
target communications.<br />
This means that some ports must be reserved for these “well<br />
known” ports.<br />
Port usage:<br />
◮ 0-1023: These ports can only be b<strong>in</strong>ded to by root<br />
◮ 1024-5000: well known ports<br />
◮ 5001-64K-1: ephemeral ports<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockets<br />
TCP<br />
UDP<br />
APIs for manag<strong>in</strong>g names and IP addresses<br />
We next consider a number of auxiliary APIs:<br />
◮ The hostent structure: describes IP, hostname pairs<br />
◮ gethostbyname: hostent of a specified mach<strong>in</strong>e<br />
◮ htons, htonl, ntohs, ntohl: byte order<strong>in</strong>g<br />
◮ <strong>in</strong>et pton, <strong>in</strong>et ntop: conversion of IP numbers between<br />
presentation and str<strong>in</strong>gs<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
gethostname<br />
sockets<br />
TCP<br />
UDP<br />
#i n c l u d e <br />
2<br />
i n t gethostname ( char ∗hostname , s i z e t nameLength )<br />
Returns the hostname of the mach<strong>in</strong>e on which this command<br />
executes (What host am i?). Returns -1 on failure, 0 on success.<br />
MAXHOSTNAMELEN is def<strong>in</strong>ed <strong>in</strong> .<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
hostent structure<br />
sockets<br />
TCP<br />
UDP<br />
s t r u c t h o s t e n t {<br />
2 char ∗h name ; // o f f i c i a l ( c a n o n i c a l ) name o f t h e h o s t<br />
char ∗∗ h a l i a s e s ; // n u l l t e r m i n a t e d a r r a y o f a l t e r n a t i v e hostnames<br />
4 i n t h a d d r t y p e ; // h o s t a d d r e s s t y p e AF INET o r AF INET6<br />
i n t h l e n g t h ; // 4 o r 16 b y t e s<br />
6 char ∗∗ h a d d r l i s t ; // IPv4 o r IPv6 l i s t o f a d d r e s s e s<br />
}<br />
Error is return through h error which can be:<br />
◮ HOST NOT FOUND<br />
◮ TRY AGAIN<br />
◮ NO RECOVERY<br />
◮ NO DATA<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Gethostbyname<br />
Auxiliary functions<br />
sockets<br />
TCP<br />
UDP<br />
#i n c l u d e <br />
2<br />
s t r u c t h o s t e n t ∗gethostbyname ( c o n s t char ∗hostname )<br />
Translates a DNS name <strong>in</strong>to a hostent.<br />
Example:<br />
s t r u c t h o s t e n t ∗ h o s t E n t i t y =<br />
2 gethostbyname ( ” b e r t . c s . u i c . edu ” ) ;<br />
memcpy ( socketAddr−>s i n a d d r ,<br />
4 h o s t E n t i t y −>h a d d r l i s t [ 0 ] ,<br />
h o s t E n t i t y −>h l e n g t h ) ;<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Network byte order<strong>in</strong>g<br />
sockets<br />
TCP<br />
UDP<br />
Network order<strong>in</strong>g <strong>in</strong> big endian. (Sparc is big endian, Intel is little<br />
endian).<br />
// Host to network b y t e o r d e r f o r s h o r t s (16 b i t )<br />
2 u i n t 1 6 t h t o n s ( u i n t 1 6 t v ) ;<br />
4 // Host to network b y t e o r d e r f o r l o n g (32 b i t )<br />
u i n t 3 2 t h t o n l ( u i n t 3 2 t v ) ;<br />
6<br />
// Network to h o s t b y t e o r d e r f o r l o n g (16 b i t )<br />
8 u i n t 1 6 t n t o h s ( u i n t 1 6 t v ) ;<br />
10 // Network to h o s t b y t e o r d e r f o r l o n g (32 b i t )<br />
u i n t 3 2 t n t o h l ( u i n t 3 2 t v ) ;<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
IP Number translation<br />
sockets<br />
TCP<br />
UDP<br />
IP address str<strong>in</strong>gs to 32 bit number<br />
In what follows, ’p’ stands for presentation.<br />
Hence, these rout<strong>in</strong>es translate between the address as a str<strong>in</strong>g and<br />
the address as the number.<br />
Hence, we have 4 representations:<br />
◮ IP number <strong>in</strong> host order<br />
◮ IP number <strong>in</strong> network order<br />
◮ Presentation (eg. dotted decimal)<br />
◮ Fully qualified doma<strong>in</strong> name<br />
Only the last needs an outside lookup to convert to one of the<br />
other formats.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
<strong>in</strong>et pton<br />
sockets<br />
TCP<br />
UDP<br />
#i n c l u d e <br />
2<br />
i n t i n e t p t o n ( i n t f a m i l y , c o n s t char ∗ s t r P t r ,<br />
4 v o i d ∗ a d d r P t r ) ;<br />
returns 1 if OK, 0 if presentation error, -1 error<br />
Where family is either AF INET or AF INET6.<br />
The strPtr is the IP address as a dotted str<strong>in</strong>g.<br />
F<strong>in</strong>ally, addrPtr po<strong>in</strong>ts to either the 32 bit result (AF INET) or<br />
128 bit result (AF INET6).<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
<strong>in</strong>et ntop<br />
sockets<br />
TCP<br />
UDP<br />
#i n c l u d e <br />
2<br />
i n t i n e t n t o p ( i n t f a m i l y , c o n s t char ∗addrPtr ,<br />
4 char ∗ s t r P t r , s i z e t l e n ) ;<br />
returns 1 if OK, 0 if presentation error, -1 error<br />
Where family is either AF INET or AF INET6.<br />
The strPtr is the return IP address as a dotted str<strong>in</strong>g.<br />
F<strong>in</strong>ally, addrPtr po<strong>in</strong>ts to either the 32 bit (AF INET) or 128 bit<br />
(AF INET6).<br />
Length is the size of dest<strong>in</strong>ation.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockets<br />
Example: TCP/IP Server Code<br />
Without error check<strong>in</strong>g.<br />
TCP<br />
UDP<br />
s o c k a d d r i n s e r v e r A d d r ;<br />
2 s o c k a d d r &s e r v e r A d d r C a s t = ( s o c k a d d r &) s e r v e r A d d r ;<br />
4 // g e t a t c p / i p s o c k e t<br />
i n t l i s t e n F d = s o c k e t ( AF INET , SOCK STREAM, 0 ) ;<br />
6<br />
b z e r o (& s e r v e r A d d r , s i z e o f ( s e r v e r A d d r ) ) ;<br />
8 s e r v e r A d d r . s i n f a m i l y = AF INET ;<br />
// any i n t e r n e t i n t e r f a c e on t h i s s e r v e r .<br />
10 s e r v e r A d d r . s i n a d d r . s a d d r = h t o n l (INADDR ANY ) ;<br />
s e r v e r A d d r . s i n p o r t = h t o n s ( 1 3 ) ;<br />
12<br />
b i n d ( l i s t e n F d , &s e r v e r A d d r C a s t , s i z e o f ( s e r v e r A d d r ) ) ;<br />
14<br />
l i s t e n ( l i s t e n F d , 5 ) ;<br />
16<br />
f o r ( ; ; ) {<br />
18 i n t connectFd =<br />
a c c e p t ( l i s t e n F d , ( s o c k a d d r ∗) NULL , NULL ) ;<br />
20 // . . r e a d and w r i t e o p e r a t i o n s on connectFd . .<br />
shutdown ( connectFd , 2 ) ;<br />
22 c l o s e ( connectFd ) ;<br />
}<br />
Note that the above is an iterative server, which means that it<br />
serves one connection at a time.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Concurrent Server<br />
To build a concurrent server:<br />
sockets<br />
TCP<br />
UDP<br />
◮ a fork is performed after the accept.<br />
◮ The child process closes listenFd, and communicates us<strong>in</strong>g<br />
connectFd.<br />
◮ The parent process closses connectFd, and then loops back to<br />
the accept to wait for another connection request.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockets<br />
Example: TCP/IP Client code<br />
TCP<br />
UDP<br />
s o c k a d d r i n s e r v e r A d d r ;<br />
2 s o c k a d d r &s e r v e r A d d r C a s t = ( s o c k a d d r &) s e r v e r A d d r ;<br />
4 // g e t a t c p / i p s o c k e t<br />
i n t sockFd = s o c k e t ( AF INET , SOCK STREAM, 0 ) ;<br />
6<br />
b z e r o (& s e r v e r A d d r , s i z e o f ( s e r v e r A d d r ) ) ;<br />
8 s e r v e r A d d r . s i n f a m i l y = AF INET ;<br />
// h o s t IP # i n d o t t e d d e c i m a l format !<br />
10 i n e t p t o n ( AF INET , serverName , s e r v e r A d d r . s i n a d d r ) ;<br />
s e r v e r A d d r . s i n p o r t = h t o n s ( 1 3 ) ;<br />
12<br />
c o n n e c t ( sockFd , s e r v e r A d d r C a s t , s i z e o f ( s e r v e r A d d r ) ) ;<br />
14 // . . r e a d and w r i t e o p e r a t i o n s on sockFd . .<br />
shutdown ( sockFd , 2 ) ;<br />
16 c l o s e ( sockFd ) ;<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockets<br />
Connectionless communication<br />
TCP<br />
UDP<br />
Communication is symmetric (peer-to-peer)<br />
◮ socket<br />
◮ b<strong>in</strong>d: b<strong>in</strong>d is optional for <strong>in</strong>itiator<br />
◮ sendto, recvfrom (repeated)<br />
◮ shutdown<br />
◮ close<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sockets<br />
Connectionless communication<br />
TCP<br />
UDP<br />
client<br />
socket<br />
b<strong>in</strong>d<br />
sendto/<br />
recvfrom<br />
shutdown<br />
close<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
UDP variations<br />
sockets<br />
TCP<br />
UDP<br />
It is not necessary for both sockets to b<strong>in</strong>d<br />
◮ The receiver gets the address of the sender<br />
It is possible for a UDP socket to connect<br />
◮ In this case, send/recv (or write/read) must be used <strong>in</strong>stead<br />
of sendto/recvfrom.<br />
◮ Asynchronous errors can be returned (us<strong>in</strong>g ICMP)<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
sendto<br />
for connectionless protocols<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
sockets<br />
TCP<br />
UDP<br />
4 i n t s e n d t o ( i n t s i d , c o n s t v o i d ∗ b u f f e r P t r ,<br />
s i z e t b u f f e r L e n g t h , i n t f l a g ,<br />
6 s t r u c t s o c k a d d r ∗addrPtr , s o c k l e n t addrLength )<br />
Send a buffer, bufferPtr, of length bufferLength to address<br />
specified by addrPtr of size addrLength. Returns number of<br />
bytes sent or -1 on error.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
ecvfrom<br />
for connectionless protocols<br />
#i n c l u d e <br />
2 #i n c l u d e <br />
sockets<br />
TCP<br />
UDP<br />
4 i n t r e c v f r o m ( i n t s i d , v o i d ∗ b u f f e r P t r , i n t b u f f e r L e n g t h ,<br />
i n t f l a g , s o c k a d d r ∗addrPtr , i n t ∗ a d d r L e n g t h P t r )<br />
Receive a buffer <strong>in</strong> bufferPtr of maximum length bufferLength<br />
from an unspecified sender.<br />
Sender address returned <strong>in</strong> addrPtr, of size *addrLengthPtr.<br />
Returns number of bytes receive or -1 on error.<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Example: UDP—server<br />
sockets<br />
TCP<br />
UDP<br />
i n t s o c k e t I d = s o c k e t ( AF INET , SOCK DGRAM, 0 ) ;<br />
2<br />
s o c k a d d r i n s e r v e r A d d r , c l i e n t A d d r ;<br />
4 s o c k a d d r &s e r v e r A d d r C a s t = ( s o c k a d d r &) s e r v e r A d d r ;<br />
6<br />
s o c k a d d r &c l i e n t A d d r C a s t = ( s o c k a d d r &) c l i e n t A d d r ;<br />
// a l l o w c o n n e c t i o n to any addr on h o s t<br />
8 // f o r h o s t s w i t h m u l t i p l e network c o n n e c t i o n s<br />
// and a s t s e r v e r p o r t .<br />
10 s e r v e r A d d r . s i n f a m i l y = AF INET ;<br />
s e r v e r A d d r . s i n p o r t = h t o n s ( s e r v e r P o r t ) ;<br />
12 s e r v e r A d d r . s i n a d d r . s a d d r = INADDR ANY ;<br />
14 // a s s o c i a t e p r o c e s s w i t h p o r t<br />
b i n d ( s o c k e t I d , &s e r v e r A d d r C a s t , s i z e o f ( addr ) ) ;<br />
16<br />
// r e c e i v e from a c l i e n t<br />
18 i n t s i z e = s i z e o f ( c l i e n t A d d r ) ;<br />
r e c v f r o m ( s o c k e t I d , b u f f e r , b u f f e r S i z e ,<br />
20 0 , c l i e n t A d d r C a s t , &s i z e ) ;<br />
22 // r e p l y to t h e c l i e n t j u s t r e c e i v e d from<br />
s e n d t o ( s o c k e t I d , b u f f e r , b u f f e r S i z e ,<br />
24 0 , c l i e n t A d d r C a s t , s i z e ) ;<br />
26 c l o s e ( s o c k e t I d ) ;<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>
Example: UDP—client<br />
sockets<br />
TCP<br />
UDP<br />
i n t s o c k e t I d = s o c k e t ( AF INET , SOCK DGRAM, 0 ) ;<br />
2<br />
s o c k a d d r i n s e r v e r A d d r , c l i e n t A d d r ;<br />
4 s o c k a d d r &s e r v e r A d d r C a s t = ( s o c k a d d r &) s e r v e r A d d r ;<br />
6<br />
s o c k a d d r &c l i e n t A d d r C a s t = ( s o c k a d d r &) c l i e n t A d d r ;<br />
// s p e c i f y s e r v e r a d d r e s s , p o r t<br />
8 s e r v e r A d d r . s i n f a m i l y = AF INET ;<br />
s e r v e r A d d r . s i n p o r t = h t o n s ( s e r v e r P o r t ) ;<br />
10 s t r u c t h o s t e n t ∗hp = gethostbyname ( hostName ) ;<br />
memcpy ( ( char ∗)& s e r v e r A d d r . s i n a d d r ,<br />
12 ( char ∗)hp−>h addr , hp−>h l e n g t h ) ;<br />
14 // no need to b i n d i f not peer−to−p e e r<br />
i n t s i z e = s i z e o f ( s e r v e r A d d r ) ;<br />
16 s e n d t o ( s o c k e t I d , b u f f e r , b u f f e r S i z e , 0 ,<br />
s e r v e r A d d r C a s t , s i z e ) ;<br />
18<br />
r e c v f r o m ( s o c k e t I d , b u f f e r , b u f f e r S i z e , 0 ,<br />
20 s e r v e r A d d r C a s t , &s i z e ) ;<br />
22 c l o s e ( s o c k e t I d ) ;<br />
c○Mani Radhakrishnan and Jon Solworth <strong>Socket</strong> <strong>Programm<strong>in</strong>g</strong> <strong>in</strong> C/<strong>C++</strong>