Title: Todays Agenda
1TCP and UDP based Socket Programming in C
2Contact Info
Avinash Gautam Chamber Number 3254-G Email
avinash_at_bits-pilani.ac.in Chamber Consultation
Hours Saturday 900 950 AM
3Definition and Components
- Sockets are nothing but a way to speak to other
programs using standard file descriptors - Everything in UNIX is a file. What it means is
that when UNIX programs do any sort of I/O, they
do it by reading or writing to a file descriptor - A file descriptor is simply an integer associated
with an open file - But this file can be a network connection, a
FIFO, a pipe, a terminal, a real on-the-disk file
etc - So when you want to communicate to another
program you are going to do it through a file
descriptor
4Definition and Components (Contd.)
- How to get a file descriptor?
- socket() system call returns socket descriptor
- Communicate through it using send() and recv()
socket calls - Two type of internet sockets
- Stream Sockets
- Datagram Sockets
- Stream sockets are referred to as "SOCK_STREAM"
and datagram sockets are referred to as
"SOCK_DGRAM" respectively. Datagram sockets are
sometime called connection less sockets
5Internet Sockets
- Stream sockets
- Reliable
- Two way communication streams
- What uses stream sockets?
- Web browser using http to get web pages from the
server - How do stream sockets achieve reliability?
- Answer TCP (RFC 793)
- Datagram sockets
- Why are they connectionless?
- Why are they unreliable?
- Answer They use IP for routing, but they dont
use TCP, - they use UDP (RFC 768)
6Internet Sockets (Contd.)
- Why datagram sockets are connectionless?
- Don't maintain an open connection
- Build a packet, attach an IP header on it with
destination information, and send it out - They are generally used for packet-by-packet
transfer of information - Any Examples?
- tftp, bootp etc
- How do these programs even work if a datagram is
lost? - Each program has its own protocol running on the
top of UDP - tftp protocol says that for each packet that gets
sent, the recipient has to send back an
acknowledgement. If the sender doesn't get a
reply and timer goes out, it will retransmit the
packet until it gets an acknowledgment
7Data types and ordering
- Various data types are used by the socket
interface - Most simplest is our friend a regular int which
is used as a socket descriptor. We will see more
in rest of the sections - Byte Ordering
- Most significant byte first also called Network
Byte Order - Least significant byte first also called Host
byte Order - Some machines store their numbers in NBO some
dont - If I say something has to be in NBO then you need
to change it to HBO by calling htons() - htons() is host-to-network-short
8Socket Structure
- struct sockaddr
-
- unsigned short sa_family // address family,
AF_xxx - char sa_data14 // 14 bytes of protocol
address -
- sa_family this remains AF_INET for stream and
datagram sockets - sa_data contains destination address and port
number for the socket
9Socket Structure
- Parallel structure to sockaddr
- struct sockaddr_in
-
- short int sin_family // Address family
- unsigned short int sin_port // Port number
- struct in_addr sin_addr // Internet address
- unsigned char sin_zero8 // same size as
sockaddr -
- sin_zero is just used to pad the structure to the
length of a structure sockaddr and hence is set
to all zeros with the function memset() - Important you can cast sockaddr_in to a pointer
of type struct sockaddr and vice versa - sin_family corresponds to sa_family and should be
set to AF_INET. - sin_port and sin_addr must be in NBO
10NBO HBO conversion functions
- Two types that can be converted
- short (two bytes)
- long (two bytes)
- Primary conversion functions
- htons() // host to network short
- htonl() // host to network long
- ntohs // network to host short
- ntohl() // network to host long
- Very Important Even if your machine is
Big-Endian m/c, but you put your bytes in NBO
before putting them on to the network for
portability
11Dealing with IP Addresses
- Suppose you have a structure
- struct sockaddr_in ina, and you want to store ip
address 10.12.110.57 in it - How will you do it? I mean this is in dotted
notation - inet_addr() at rescue this function converts IP
address in dotted notation into an unsigned long,
example- - ina.sin_addr.s_addr inet_addr(10.12.110.57)
- inet_addr returns the IP in NBO, you need not
call htonl() - inet_addr returns -1 on error
- Note In binary -1 corresponds to IP address
255.255.255.255, which is actually a broadcast
address and is wrong - PLZ HANDLE ERRORS PROPERLY
12Dealing with IP Addresses (Contd.)
- Convert binary representation of IP address back
to string IP - Use inet_ntoa() // network to ascii
- Example
- printf(s, inet_ntoa(ina.sin_addr))
- inet_ntoa accepts structure in_addr not a long.
- At this point function return a pointer to a
char, which points to a statically stored char
array with in inet_ntoa() so that each time you
call inet_ntoa() it will overwrite the last IP
address you asked for.
13Dealing with IP Addresses (Contd.)
- Example
- char ip1, ip2
-
-
-
- ip1 inet_ntoa(ina1.sin_addr) // this is
192.168.4.14 - ip2 inet_ntoa(ina2.sin_addr) // this is
10.12.110.57 - printf(Address 1 s\n, a1)
- printf(Address 2 s\n, a2)
- Output
- Address 1 10.12.110.57
- Address 2 10.12.110.57
- If you want to save the address use strcpy() it
to your own array - We will learn to convert hostname to IP address
in sections to come
14Socket Library Function
- System calls
- startup / close
- data transfer
- options control
- Network configuration lookup
- host address
- ports for services
- Utility functions
- data conversion
- address manipulation
- error handling
15Network Database Administration functions
- gethostbyname - given a hostname, returns a
structure which specifies its DNS name(s) and IP
address(es) - getservbyname - given service name and protocol,
returns a structure which specifies its name(s)
and its port address - gethostname - returns hostname of local host
- getservbyname, getservbyport, getservent
- getprotobyname, getprotobynumber, getprotobyent
- getnetbyname, getnetbyaddr, getnetent
16Socket Utility Functions
- ntohs/ntohl - convert short/long from network
byte order (big endian) to host byte order - htons/htonl - convert short/long from host byte
order to network byte order - inet_ntoa/inet_addr - convert 32-bit IP address
(network byte order to/from a dotted decimal
string) - perror() - print error message (based on errno)
to stderr - herror() - print error message for
gethostbyname() to stderr (used with DNS)
17Primary Header Files
- Include file sequence may affect processing
(order is important!) - ltsys/types.hgt - prerequisite typedefs
- lterrno.hgt - names for errno values (error
numbers) - ltsys/socket.hgt - struct sockaddr system
prototypes and constants - ltnetdb.h.hgt - network info lookup prototypes and
structures - ltnetinet/in.hgt - struct sockaddr_in byte
ordering macros - ltarpa/inet.hgt - utility function prototypes
18Primary Socket System Calls
- socket() - create a new socket and return its
descriptor - bind() - associate a socket with a port and
address - listen() - establish queue for connection
requests - accept() - accept a connection request
- connect() - initiate a connection to a remote
host - recv() - receive data from a socket descriptor
- send() - send data to a socket descriptor
- close() - one-way close of a socket descriptor
19Socket System Calls For Connection-Oriented
Protocols
20Socket System Calls For Connectionless Protocols
21Socket Addresses
- Socket address structure from ltnetinet/in.hgt
- struct sockaddr_in (IPv4)
struct sockaddr_in uint8_t sin_len sa_fami
ly_t sin_family in_port_t sin_port struct
in_addr sin_addr char sin_zero8
struct in_addr in_addr_t
s_addr
22include ltsys/types.hgt include
ltsys/socket.hgt int socket (int family, int type,
int protocol)
Socket descriptor -1 if fails
Usually 0 is used. Defined in ltnetinet/in.hgt IPPRO
TO_xxx
AF_INET Internet protocols(IPv4) AF_INET6
IPv6 protocol
AF_UNIX AF_INET
SOCK_STREAM Stream Socket SOCK_DGRAM Datagram
Socket
SOCK_STREAM SOCK_DGRAM
- Creates a network plug point that enables the
client/server to communicate
23- Bind System Call
- Servers register their addresses with the system.
- Both CO and CL servers do this before accepting
client requests. - Allows a server to specify the IP address and
port number associated with a socket - connect System Call
- Enables a client to connect to a server i.e.
initiate a connection to a remote host - Client process connects a socket descriptor to
establish a connection with the server - Specific communication parameters like buffer
size, size of data to be exchanged without ACK,
etc, is agreed
Pointer to a protocol-specific address
include ltsys/types.hgt include
ltsys/socket.hgt int bind(int sockfd,const struct
sockaddr myaddr,int addrlen)
include ltsys/types.hgt include
ltsys/socket.hgt int connect(int sockfd,struct
sockaddr servaddr,int addrlen)
24- listen System Call
- Used to indicate that it is willing to receive
connections - backlog specifies the number of requests that can
be queued by the system, while it waits for the
server to execute the accept system call - accept System Call
- After listen, accept waits for an actual
connection request from a client - Takes the first connection request from queue,
and creates another socket with the same
properties as sockfd - accept called to return next completed connection
from the front of completed connection queue
int listen (int sockfd, int backlog)
include ltsys/types.hgt include
ltsys/socket.hgt int accept (int sockfd, struct
sockaddr peer, int addrlen)
25Either zero, or ORed with MSG_OOB
Out-of-band MSG_PEEK Peek at data
MSG_DONTROUTE Bypass routing
include ltsys/types.hgt include
ltsys/socket.hgt int write (int connfd, char
buff, int nbytes) int sendto (int sockfd, char
buff, int nbytes, int flags, struct sockaddr
to, int addrlen) int read (int connfd, char
buff, int nbytes) int recvfrom (int sockfd,
char buff, int nbytes, int flags, struct
sockaddr from, int addrlen)
- All return the length of data that was read or
written as the value of the function - Close System Call
int close (int fd)
26- Byte ordering routines
- Address conversion routines
include ltsys/types.hgt include
ltnetinet/in.hgt u_long htonl(u_long hostlong)
/ host-to-network, long integer / u_short
htons(u_short hostshort) / host-to-network,
short integer / u_long ntohl(u_long netlong)
/ network-to-host, long integer / u_short
ntohs(u_short netshort) / network-to-host,
short integer /
include ltsys/socket.hgt include
ltnetinet/in.hgt include ltarpa/inet.hgt unsigned
long inet_addr(char ptr) converts a char
string IP address to its 32-bit network
byte-order integer equivalent. char
inet_ntoa(struct in_addr inaddr)
27Simple TCP Server
- include ltsys/types.hgt
- include ltsys/socket.hgt
- include ltnetinet/in.hgt
- define SERVER_PORT 5888
- int main()
- int sockfd, connfd,clilen,n
- char buf256
- struct sockaddr_in servaddr, cliaddr
-
- sockfd socket( AF_INET, SOCK_STREAM, 0)
- if (sockid lt 0)
- printf( Server socket error")
exit(1) - servaddr.sin_family AF_INET
- servaddr.sin_port htons(SERVER_PORT)
- servaddr.sin_addr.s_addr htonl(INADDR_ANY)
- if(bind(sockfd,(struct sockaddr)servaddr,sizeof(
server)) lt0 ) - printf(Server Bind Error) exit(1)
28- listen(sockfd, 5)
- for( )
- clilen sizeof(cliaddr)
- connfdaccept(sockfd, (struct sockaddr )
cliaddr, clilen) -
- if(connfdlt0)
- printf(Server Accept error \n) exit(1)
- printf("Client IP s\n", inet_ntoa(cliaddr.sin_a
ddr)) - printf("Client Port hu\n", ntohs(cliaddr.sin_po
rt)) - n read(connfd, buf,256)
- printf("Server read \"s\" d chars\n",
buf, n) -
- write(connfd, Server Got Message, 18)
- close(connfd)
-
29Simple TCP Client
- include ltsys/types.hgt
- include ltsys/socket.hgt
- include ltnetinet/in.hgt
- define SERVER_PORT 5888
- define SERVER_IPADDR 172.24.2.4
- int main()
- int sockfd, clifd,len
- char buf256
- struct sockaddr_in servaddr
- sockfd socket( AF_INET, SOCK_STREAM, 0)
- if (sockid lt 0) printf( Server socket
error") exit(1) - servaddr.sin_family AF_INET
- servaddr.sin_port htons(SERVER_PORT)
- servaddr.sin_addr.s_addr
inet_addr(SERVER_IPADDR) - connect(sockfd,(struct sockaddr)servaddr,
sizeof(servaddr)) - print(Enter Message \n)
30Simple UDP Server
- include ltsys/types.hgt
- include ltsys/socket.hgt
- include ltnetinet/in.hgt
- define SERVER_PORT 9988
- int main()
- int sockfd, clilen
- char buf256
- struct sockaddr_in servaddr, cliaddr
- sockfd socket( AF_INET, SOCK_DGRAM, 0)
- servaddr.sin_family AF_INET
- servaddr.sin_port htons(SERVER_PORT)
- servaddr.sin_addr.s_addr htonl(INADDR_ANY)
- if (bind(sockfd,(struct sockaddr)servaddr,sizeof
(servaddr)) lt0 ) - printf(Server Bind Error) exit(1)
- for( )
- clilen sizeof(cliaddr)
- recvfrom(sockfd,buf,256,0,(struct
sockaddr)cliaddr,clilen) - printf(Server Receiveds\n,buf)
31Simple UDP Client
- include ltsys/types.hgt
- include ltsys/socket.hgt
- include ltnetinet/in.hgt
- define SERVER_PORT 9988
- define SERVER_IPADDR 172.24.2.4
- int main()
- int sockfd,len
- char buf256
- struct sockaddr_in ,cliaddr,servaddr
-
- servaddr.sin_family AF_INET
- servaddr.sin_port htons(SERVER_PORT)
- servaddr.sin_addr.s_addr
inet_addr(SERVER_IPADDR) -
- sockfd socket( AF_INET, SOCK_DGRAM, 0)
- cliaddr.sin_family AF_INET
- cliaddr.sin_port htons(0)
- cliaddr.sin_addr.s_addr htonl(INADDR_ANY)
Not mandatory
32THANK YOU