You are on page 1of 40

sockets

Socket Programming in C/C++


c Mani Radhakrishnan and Jon Solworth September 24, 2004

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

Contact Info

Mani Radhakrishnan Office 4224 SEL email mradhakr @ cs . uic . edu Office Hours Tuesday 1 - 4 PM

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Introduction

Sockets are a protocol independent method of creating a connection between processes. Sockets can be either connection based or connectionless: Is a connection established before communication or does each packet describe the destination? packet based or streams based: Are there message boundaries or is it one stream? reliable or unreliable. Can messages be lost, duplicated, reordered, or corrupted?

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Socket characteristics

Socket are characterized by their domain, type and transport protocol. Common domains are: AF UNIX: address format is UNIX pathname AF INET: address format is host and port number Common types are: virtual circuit: received in order transmitted and reliably datagram: arbitrary order, unreliable

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Socket characteristics (contd)

Each socket type has one or more protocols. Ex: TCP/IP (virtual circuits) UDP (datagram) Use of sockets: Connectionbased sockets communicate client-server: the server waits for a connection from the client Connectionless sockets are peer-to-peer: each process is symmetric.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Socket APIs
socket: creates a socket of a given domain, type, protocol (buy a phone) bind: assigns a name to the socket (get a telephone number) listen: species the number of pending connections that can be queued for a server socket. (call waiting allowance) accept: server accepts a connection request from a client (answer phone) connect: client requests a connection request to a server (call) send, sendto: write to connection (speak) recv, recvfrom: read from connection (listen) shutdown: end the call
c Mani Radhakrishnan and Jon Solworth Socket Programming in C/C++

sockets

TCP UDP

Connection-based communication
Server performs the following actions socket: create the socket bind: give the address of the socket on the server listen: species the maximum number of connection requests that can be pending for this process accept: establish the connection with a specic client send,recv: stream-based equivalents of read and write (repeated) shutdown: end reading or writing close: release kernel data structures

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

TCP client

Client performs the following actions socket: create the socket connect: connect to a server send,recv: (repeated) shutdown close

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

TCP-based sockets
server socket client socket

bind

connect

listen

accept

close

send/recv

send/recv

shutdown

shutdown

close

close

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

socket API
#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 i n t s o c k e t ( i n t domain , i n t t y p e , i n t p r o t o c o l ) ;

Returns a le descriptor (called a socket ID) if successful, -1 otherwise. Note that the socket returns a socket descriptor which is the same as a le descriptor. The domain is AF INET. The type argument can be: SOCK STREAM: Establishes a virtual circuit for stream SOCK DGRAM: Establishes a datagram for communication SOCK SEQPACKET: Establishes a reliable, connection based, two way communication with maximum message size. (This is not available on most machines.) protocol is usually zero, so that type denes the connection within domain.
c Mani Radhakrishnan and Jon Solworth Socket Programming in C/C++

sockets

TCP UDP

bind
#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 i n t bind ( i n t sid , s t r u c t sockaddr addrPtr , i n t l e n )

Where sid: is the socket id addrPtr: is a pointer to the address family dependent address structure len: is the size of *addrPtr Associates a socket id with an address to which other processes can connect. In internet protocol the address is [ipNumber, portNumber]

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

sockaddr
For the internet family:
2 struct sockaddr sa family t in port t 4 struct in addr } in { s i n f a m i l y ; // = AF INET sin port ; // i s a p o r t number sin addr ; // an I P a d d r e s s

For unix sockets (only works between processes on the same machine)
2 4 struct sockaddr un { uint8 t sun length ; short sun family ; char sun path [ 1 0 0 ] ; // // = AF LOCAL // n u l l t e r m i n a t e d pathname // ( 1 0 0 i s p o s i x 1 . g minimum )

6 }

When using internet sockets, the second parameter of bind (of type sockaddr in *) must be cast to (sockaddr *).

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

listen

#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 int l i s t e n ( int sid , int size );

Where size it the number of pending connection requests allowed (typically limited by Unix kernels to 5). Returns the 0 on success, or -1 if failure.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

accept

#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 i n t accept ( i n t sid , s t r u c t sockaddr addrPtr , i n t l e n P t r )

Returns the socketId and address of client connecting to socket. if lenPtr or addrPtr equal zero, no address structure is returned. lenPtr is the maximum size of address structure that can be called, returns the actual value. Waits for an incoming request, and when received creates a socket for it.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

accept styles
There are basically three styles of using accept: Iterating server: Only one socket is opened at a time. When the processing on that connection is completed, the socket is closed, and next connection can be accepted. Forking server: After an accept, a child process is forked o to handle the connection. Variation: the child processes are preforked and are passed the socketId. Concurrent single server: use select to simultaneously wait on all open socketIds, and waking up the process only when new data arrives.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Pro and Con of Accept styles

Iterating server is basically a low performance technique since only one connection is open at a time. Forking servers enable using multiple processors. But they make sharing state dicult, unless performed with threads. Threads, however present a very fragile programming environment. Concurrent single server: reduces context switches relative to forking processes and complexity relative to threads. But does not benet from multiprocessors.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

send

#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 i n t send ( i n t sid , const char b u f f e r P t r , i n t len , i n t f l a g )

Send a message. Returns the number of bytes sent or -1 if failure. (Must be a bound socket). ag is either 0: default MSG OOB: Out-of-band high priority communication

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

recv

#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 i n t recv ( i n t sid , char b u f f e r P t r , i n t len , i n t f l a g s )

Receive up to len bytes in bufferPtr. Returns the number of bytes received or -1 on failure. ags can be either 0: default MSG OOB: out-of-bound message MSG PEEK: look at message without removing

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

shutdown

#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 i n t shutdown ( i n t s i d , i n t how )

Disables sending (how=1 or how=2) or receiving (how=0 or how=2). Returns -1 on failure. acts as a partial close.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

connect

this is the rst of the client calls


#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 i n t connect ( i n t sid , s t r u c t sockaddr addrPtr , i n t l e n )

Species the destination to form a connection with (addrPtr), and returns a 0 if successful, -1 otherwise.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Denoting Connections

Note that a connection is denoted by a 5-tuple: from IP from port protocol to IP to port So that multiple connections can share the same IP and port.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Port usage

Note that the initiator of communications needs a xed port to target communications. This means that some ports must be reserved for these well known ports. Port usage: 0-1023: These ports can only be binded to by root 1024-5000: well known ports 5001-64K-1: ephemeral ports

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

APIs for managing names and IP addresses

We next consider a number of auxiliary APIs: The hostent structure: describes IP, hostname pairs gethostbyname: hostent of a specied machine htons, htonl, ntohs, ntohl: byte ordering inet pton, inet ntop: conversion of IP numbers between presentation and strings

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

gethostname

#i n c l u d e < u n i s t d . h> 2 i n t g e t h o s t n a m e ( c h a r hostname , s i z e t nameLength )

Returns the hostname of the machine on which this command executes (What host am i?). Returns -1 on failure, 0 on success. MAXHOSTNAMELEN is dened in <sys/param.h>.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

hostent structure

struct hostent { c h a r h name ; c h a r h a l i a s e s ; 4 int h addrtype ; int h length ; 6 c h a r h a d d r l i s t } 2

// // // // ; //

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 n u l l t e r m i n a t e d a r r a y of a l t e r n a t i v e hostnames h o s t a d d r e s s t y p e AF INET o r AF INET6 4 o r 16 b y t e s IPv4 or IPv6 l i s t of a d d r e s s e s

Error is return through h error which can be: HOST NOT FOUND TRY AGAIN NO RECOVERY NO DATA

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Gethostbyname

Auxiliary functions
#i n c l u d e <n e t d b . h> 2 s t r u c t h o s t e n t g e t h o s t b y n a m e ( c o n s t c h a r hostname )

Translates a DNS name into a hostent. Example:


struct hostent hostEntity = g e t h o s t b y n a m e ( b e r t . c s . u i c . edu ) ; memcpy ( s o c k e t A d d r >s i n a d d r , 4 hostEntity >h a d d r l i s t [ 0 ] , hostEntity >h l e n g t h ) ; 2

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Network byte ordering

Network ordering in big endian. (Sparc is big endian, Intel is little endian).
2 // Host t o n e t w o r k b y t e o r d e r f o r s h o r t s ( 1 6 b i t ) u i n t 1 6 t htons ( u i n t 1 6 t v ) ; o r d e r f o r long (32 b i t ) v ); o r d e r f o r long (16 b i t ) v );

4 // Host t o n e t w o r k b y t e uint 32t htonl ( uint 32t 6 // Network t o h o s t b y t e 8 u i n t 1 6 t ntohs ( u i n t 1 6 t

10 // Network t o h o s t b y t e o r d e r f o r l o n g ( 3 2 b i t ) uint 32t ntohl ( uint 32t v );

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

IP Number translation
IP address strings to 32 bit number In what follows, p stands for presentation. Hence, these routines translate between the address as a string and the address as the number. Hence, we have 4 representations: IP number in host order IP number in network order Presentation (eg. dotted decimal) Fully qualied domain name Only the last needs an outside lookup to convert to one of the other formats.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

inet pton

#i n c l u d e <a r p a / i n e t . h> 2 4 i n t i n e t p t o n ( i n t family , const char strPtr , void addrPtr ) ;

returns 1 if OK, 0 if presentation error, -1 error Where family is either AF INET or AF INET6. The strPtr is the IP address as a dotted string. Finally, addrPtr points to either the 32 bit result (AF INET) or 128 bit result (AF INET6).

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

inet ntop

#i n c l u d e <a r p a / i n e t . h> 2 4 i n t i n e t n t o p ( i n t family , const char addrPtr , char s tr Pt r , s i z e t l e n ) ;

returns 1 if OK, 0 if presentation error, -1 error Where family is either AF INET or AF INET6. The strPtr is the return IP address as a dotted string. Finally, addrPtr points to either the 32 bit (AF INET) or 128 bit (AF INET6). Length is the size of destination.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Example: TCP/IP Server Code


Without error checking.
sockaddr in serverAddr ; 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 ; 4 // g e t a t c p / i p s o c k e t i n t l i s t e n F d = s o c k e t ( AF INET , SOCK STREAM , 0 ) ; 6 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 ) ) ; 8 s e r v e r A d d r . s i n f a m i l y = AF INET ; // 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 . 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 ) ; serverAddr . s i n p o r t = htons ( 1 3 ) ; 12 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 ) ) ; 14 l i s t e n ( listenFd , 5); 16 for ( ; ; ) { 18 i n t connectFd = a c c e p t ( l i s t e n F d , ( s o c k a d d r ) NULL , NULL ) ; 20 // . . r e a d and w r i t e o p e r a t i o n s on c o n n e c t F d . . shutdown ( c o n n e c t F d , 2 ) ; 22 c l o s e ( connectFd ) ; }

Note that the above is an iterative server, which means that it serves one connection at a time.
c Mani Radhakrishnan and Jon Solworth Socket Programming in C/C++

sockets

TCP UDP

Concurrent Server

To build a concurrent server: a fork is performed after the accept. The child process closes listenFd, and communicates using connectFd. The parent process closses connectFd, and then loops back to the accept to wait for another connection request.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Example: TCP/IP Client code

sockaddr in serverAddr ; 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 ; 4 // g e t a t c p / i p s o c k e t i n t s o c k F d = s o c k e t ( AF INET , SOCK STREAM , 0 ) ; 6 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 ) ) ; 8 s e r v e r A d d r . s i n f a m i l y = AF INET ; // h o s t I P # i n d o t t e d d e c i m a l f o r m a t ! 10 i n e t p t o n ( AF INET , s e r v e r N a m e , s e r v e r A d d r . s i n a d d r ) ; serverAddr . s i n p o r t = htons ( 1 3 ) ; 12 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 ) ) ; 14 // . . r e a d and w r i t e o p e r a t i o n s on s o c k F d . . shutdown ( sockFd , 2 ) ; 16 c l o s e ( s o c k F d ) ;

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Connectionless communication

Communication is symmetric (peer-to-peer) socket bind: bind is optional for initiator sendto, recvfrom (repeated) shutdown close

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Connectionless communication
client socket

bind

sendto/ recvfrom shutdown

close

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

UDP variations

It is not necessary for both sockets to bind The receiver gets the address of the sender It is possible for a UDP socket to connect In this case, send/recv (or write/read) must be used instead of sendto/recvfrom. Asynchronous errors can be returned (using ICMP)

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

sendto

for connectionless protocols


#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 6 i n t sendto ( i n t sid , const void bufferPtr , s i z e t bufferLength , int flag , s t r u c t sockaddr addrPtr , s o c k l e n t addrLength )

Send a buer, bufferPtr, of length bufferLength to address specied by addrPtr of size addrLength. Returns number of bytes sent or -1 on error.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

recvfrom

for connectionless protocols


#i n c l u d e < s y s / t y p e s . h> 2 #i n c l u d e < s y s / s o c k e t . h> 4 int recvfrom ( int sid , void bufferPtr , int bufferLength , i n t f l a g , sockaddr addrPtr , i n t addrLengthPtr )

Receive a buer in bufferPtr of maximum length bufferLength from an unspecied sender. Sender address returned in addrPtr, of size *addrLengthPtr. Returns number of bytes receive or -1 on error.

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Example: UDPserver
i n t s o c k e t I d = s o c k e t ( AF INET , SOCK DGRAM, 0 ) ; 2 4 6 8 10 12 14 16 18 20 22 24 26 // r e c e i v e from a c l i e n t int size = sizeof ( clientAddr ); recvfrom ( socketId , buffer , bufferSize , 0 , c l i e n t A d d r C a s t , &s i z e ) ; // r e p l y t o t h e c l i e n t j u s t r e c e i v e d from sendto ( socketId , buffer , bufferSize , 0 , clientAddrCast , size ); close ( socketId ); // a l l o w c o n n e c t i o n t o any a d d r on h o s t // f o r h o s t s w i t h m u l t i p l e n e t w o r k c o n n e c t i o n s // and a s t s e r v e r p o r t . s e r v e r A d d r . s i n f a m i l y = AF INET ; serverAddr . sin port = htons ( s e r v e r P o r t ) ; s e r v e r A d d r . s i n a d d r . s a d d r = INADDR ANY ; // a s s o c i a t e p r o c e s s w i t h p o r t 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 ( a d d r ) ) ; sockaddr in serverAddr , clientAddr ; 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 ; 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 ;

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

sockets

TCP UDP

Example: UDPclient
i n t s o c k e t I d = s o c k e t ( AF INET , SOCK DGRAM, 0 ) ; 2 4 6 8 10 12 14 16 18 20 22 recvfrom ( socketId , buffer , bufferSize , 0 , s e r v e r A d d rC a s t , &s i z e ) ; close ( socketId ); // s p e c i f y s e r v e r a d d r e s s , p o r t s e r v e r A d d r . s i n f a m i l y = AF INET ; serverAddr . sin port = htons ( s e r v e r P o r t ) ; s t r u c t h o s t e n t hp = g e t h o s t b y n a m e ( hostName ) ; memcpy ( ( c h a r )& s e r v e r A d d r . s i n a d d r , ( c h a r ) hp >h a d d r , hp >h l e n g t h ) ; // no n e e d t o b i n d i f n o t p e e r top e e r int size = sizeof ( serverAddr ); sendto ( socketId , buffer , bufferSize , 0 , serverAddrCast , s i z e ) ; sockaddr in serverAddr , clientAddr ; 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 ; 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 ;

c Mani Radhakrishnan and Jon Solworth

Socket Programming in C/C++

You might also like