Ix Ne TW Ork Gra MM Ing: R.H.Goudar Associate Professor, Dept. of CS/IT
Ix Ne TW Ork Gra MM Ing: R.H.Goudar Associate Professor, Dept. of CS/IT
e tw g
N in
ix m m By
n
U ogr a
R.H.Goudar
B.E(CSE),M.Tech(CNE),(Ph.D-CSE)
rhgoudar@gmail.com
Lesson Plan
1: TCP/IP Basics
1.1 TCP/IP
2: Network Programming
Berkley Sockets
Introduction –Compare netI/O with fileI/O
Overview- Socket System Calls for Connection-oriented & Connectionless
Unix Domain Protocols
Socket Addresses
Elementary System Calls
Client Server Example : SERVER Program CLIENT Program
Advanced System calls
Reserved Ports
Stream Pipes
Passing File Descriptors.
Socket options.
Asynchronous I/O.
Input/Output Multiplexing.
Sockets & Signals.
Internet Superuser.
Elementary Socket System Calls
socket
bind
connect
listen
accept
Iterative & Concurrent Server Examples
send, sendto, recv,recvfrom,close
Byte Ordering Routines
Byte Operations
Address Conversion Routines
Berkeley Sockets
Compare File I/O to Network I/O
1.For a Unix file, there are six system calls for input & output ; open, creat, close,read,
write & lseek.
But the network I/O involves more details & options than file I/O.
bind()
listen()
accept() Client
socket()
Block until connection from client
Connection Establishment
connect()
Data Request
write()
read()
Process request
Data Reply
write() read()
Fig: Socket System calls for Connection-oriented protocol
Server
socket()
bind()
Client
socket()
recvfrom()
bind()
Block until data received
from client
Data (Request)
sendto()
Process request
recvfrom()
Fig: Socket System calls for Connectionless protocol
Unix Domain Protocols
Sockets in the domain can only be used to communicate
with processes on the same Unix System.
4.3 BSD supports Unix Domain Protocols.
4.3 BSD provides both a connection-oriented & a
connectionless interface to the Unix domain protocols.
Both can considered reliable, since they exist oonly within
the kernel & are not transmitted across external facilities
such as communication line between systems.
The Unix domain protocols provide a feature that is not
currently provided by any other protocol family: The
ability to pass access rights from one process to another.
Unix Domain continued….
struct sockaddr_in {
short sin_family;/* AF_INET*/
u_short sin_port;/* 16-bit port number */
struct in_addr sin_addr; /* 32-bit netid/hostid*/
/* network byte ordered */
char sin_zero[8]; /* unused*/
};
Socket Address Structures
6-byte host ID
The protocol argument to the socket system call is typically set to 0 for must user
applications. There are specialized applications, however, that specify a protocol
value to use a specific protocol. The valid combinations are shown in fig below.
family type protocol Actual protocol
AF_INET SOCK_DGRAM IPPROTO_UDP UDP
AF_INET SOCK_STREAM IPPROTO_TCP TCP
AF_INET SOCK_DGRAM IPPROTO_UDP ICMP
AF_NS SOCK_STREAM NSPROTO_SPP SPP
AF_NS SOCK_SEQPACKET NSPROTO_SPP SPP
AF_NS SOCK_RAW NSPROTO_ERROR ERROR protocol
The Socket system call specifies is one element of this tuple, the protocol.
The Socket system call returns a small integer value, similar to a file
descriptor.
bind system call
bind System call
The bind system call assigns a name to an unnamed socket.
#include<sys/types.h>
#include<sys/socket.h>
The connect & bind system calls require only the pointer to the address structure
& its size as arguments, not the protocol;
listen system call
This system call is used by a connection-oriented server to indicate that it is
willing to receive connections.
It is executed after both the socket & bind system calls & immediately
before the accept system call.
Most Connection-Oriented servers are Concurrent servers & not iterative servers
Iterative Server example
int sockfd, newsockfd;
if(( sockfd=socket(…))<0)
err_sys(“socket error”);
if( bind(sockfd,…)<0)
err_sys(“bind error”);
if( listen(sockfd,5)<0)
err_sys(“listen error”);
for(;;){
newsockfd=accept(sockfd,…); /* blocks */
if(newsockfd<0)
err_sys(“accept error”);
doit(newsockfd); /* process the request */
close(newsockfd);
}
send,sendto,recv & recvfrom System Calls
Similar calls to the std. read & write system calls.
#include<sys/types.h>
#include<sys/socket.h>
int send( int sockfd, char * buff, int nbytes, int flags);
int sendto( int sockfd, char *buff, int nbytes,int flags, struct sockadrr *to, int addrlen);
int recv( int sockfd, char *buff, int nbytes, int flags);
int recvfrom( int sockfd, char *buff, int nbytes, int flags, struct sockaddr *from, int
*addrlen);
The flags argument is either zero, or is formed by or’ing one of the following
constants.
MSG_OOB send or receive out-of-band data.
MSG_PEEK peek at incoming message.(recv or recvfrom)
#include<sys/types.h>
#include<netinet.h>
u_long htonl (u_long hostlong);
u_short htons(u_short hostshort);
u_long ntohl( u_long netlong);
u_short ntohs( u_short netshort);
short – 16 bits
long – 32 bits
Byte Operations
#include<sys/types.h>
Socket
#include<sys/socket.h>
#include<stdio.h>
#include<netinet/in.h>
Address Conversion Routines
#include<arpa/inet.h>
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
printf(“Server can’t open stream socket\n”);
bzero((char *)&serv_addr,sizeof(serv_addr));
Server Program continued…
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERV_TCP_PORT);
serv_addr.sin_addr.s_addr=inet_addr(SERV_HOST_ADDR
);
//inet_addr- converts a dotted-decimal notation to a 32 bit
Internet address.
if(bind(sockfd,
(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)
//bind local addrs so that client can send to us
printf(“Server can’t bind local addr\n”);
listen(sockfd,1);
Server Program continued…
for(;;)
{
//wait for a connection from a client process-this is an example of
concurrent server.
clilen=sizeof(cli_addr);
newsockfd=accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
if(newsockfd<0)
printf(“Server accept error\n”);
if((childpid=fork())<0)
printf(“Server fork error \n”);
else
if(childpid==0)
//child process
Server Program continued…
printf(“ pid is %d\n”,childpid);
close(sockfd);
//close original socket.
read( newsockfd,buf,6);
buf[6]=‘\0’;
printf(“Server reads ‘%s’ \n”,buf);
write(newsockfd,”HELLO I RECEIVED”,16);
exit(0);
}
close(newsockfd);
//parent process
}
}
Client Program
#include<sys/types.h>
Socket
#include<sys/socket.h>
#include<stdio.h>
#include<netinet/in.h>
Address Conversion Routines
#include<arpa/inet.h>
if((sd=socket(AF_INET,SOCK_STREAM,0))<0)
printf(“Server can’t open stream socket\n”);
bzero((char *)&serv_addr,sizeof(serv_addr));
Client Program continued…
serv_addr.sin_family=AF_INET;
serv_addr.sin_port=htons(SERV_TCP_PORT);
serv_addr.sin_addr.s_addr=inet_addr(SERV_HOST_ADDR);
//inet_addr- converts a dotted-decimal notation to a 32 bit Internet
address.
If(connect(sd,(struct sockaddr *) &serv_addr, sizeof(serv_addr))<0)
printf(“Client :can’t connect to server \n”);
write(sd,”hi guy”,6);
read(sd,buf,16);
buf[16]=‘\0’;
printf(“ Client recieves %s\n”,buf);
}
Advanced Socket System Calls
#include<sys/types.h>
#include<sys/socket.h>
int sendmsg(int sockfd, struct msghdr msg[], int flags);
int recvmsg(int sockfd, struct msghdr msg[], int flags);
msghdr structure header defined in <sys/socket.h>
struct msghdr{
caddr_t msg_name;/* optional address */
int msg_namelen; /*size of address */
struct iovec *msg_iov;
int msg_iovlen;
caddr_t msg_accrights;
int msg_accrightslen;
};
getpeername System Call
#include<sys/types.h>
#include<sys/socket.h>
int getpeername(int sockfd, struct
sockaddr *peer, int *addrlen);
getsockname System Call
#include<sys/types.h>
#include<sys/socket.h>
int getsockname(int sockfd, struct
sockaddr *peer, int *addrlen);
shutdown System Call
#include<sys/types.h>
#include<sys/socket.h>
int s_pipe(intfd[2])
`{
return(socketpair(AF_UNIX,SOCK_STREAM,0,
fd));
}
Passing File Descriptors
Process Table Entry
f
dfd0
0
fd1
fd0
fd1
fd2
...
Fig: Sharing a file table entry between two processes
Socket Options
#include<sys/types.h>
#include<sys/socket.h>
int getsockopt( int sockfd, int level, int optname,
char *optval, int *optlen);
IPPROTO_TCP
TCP_MAXSEG Ethernet ->1024bytes
TCP_NODELAY
TCP_NODELAY :Send the data as
soon as possible
optval specifies the DataType
optlen specifies the length of the optval
Level-> XNS or TCP/IP
fcntl System Call
Users can use fcntl to assign multiple file descriptors to reference
the same file.
#include<fcntl.h>
int fcntl(int fdesc, int cmd,…);
The cmd argument specifies which operations to perform on
a file referenced by the fdesc argument.
Cmd values are F_GETOWN,F_SETOWN,F_GETFL & F_SETFL.
F_SETOWN command sets the processID to receive the SIGIO
signals for the socket associated with fd.
F_GETOWN returns the value of fcntl.
F_SETFL :
F_GETFL : based on flags
FNDELAY :
This option designates the socket as “nonblocking”.An
I/O request that cannot complete & return is made to
the caller immediately with the errno.
FASYNC:
This option allows the receipt of asynchronous I/O
signals.The SIGIO signal is sent to the process group
of the socket when data is available to be read.
Asynchronous I/O
Asynchronous I/O allows the process to tell the kernel to notify it
when a specified descriptor is ready for I/O.It is called the signal-
driven I/O.
The notification from the kernel to the user process takes place
with a signal, the SIGIO signal.
To do asynchronous I/O, a process must perform the following
three steps:
1.The process must establish a handler for the SIGIO signal.This is
done by calling the signal call.
2. The process must set the process ID to receive the SIGIO
signals.This is done with the fcntl system call, with the
F_SETOWN command.
3. The Process must enable asynchronous I/O using the fcntl
system call, with the F_SETFL command & the FASYNC
argument.
Input/Output Multiplexing
Consider a process that reads input from one source. It opens two
sockets one to receive print requests from processes on the same
host & to receive print requests from processes on other hosts.
Since it doesn’t know when requests will arrive on the two sockets, it
can’t start a read on one socket, as it could block while waiting for a
request on that socket, & in the mean time a request can arrive on
the other socket.
Techniques available to handle multiplexing of different I/O Channels
1.It can set both sockets to nonblocking, using either the FNDELAY flag
to fcntl.The process has execute a loop that reads from each socket
& if nothing is available to read, wait some amount of time before
trying the reads again.This is called polling.
Polling can waste computer resources, since most of the time there
is no work to be done.
2.The process can fork one child process to handle each
I/O channel.
3. Asynchronous I/O can be used.
4.Another technique is provided with the select system call.
This system call allows the user process to instruct the
kernel to wait for any one of multiple events to occur & to
wake up the process only when one of these events
occurs.
The prototype for the system call is
#include<sys/types.h>
#include<sys/time.h>
int select(int maxfdp1, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
struct timeval{
long tv_sec; /*seconds */
long tv_usec; /* microseconds */
}l
Sockets & Signals