0% found this document useful (0 votes)
98 views74 pages

I. Introduction To Socket Programming: Struct Sockaddr

The document provides an overview of socket programming concepts. It describes the elementary system calls used for socket programming like socket(), bind(), connect(), listen(), accept(), send(), recv() and close(). It also discusses socket address structures and byte ordering routines for converting between big-endian and little-endian formats.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
98 views74 pages

I. Introduction To Socket Programming: Struct Sockaddr

The document provides an overview of socket programming concepts. It describes the elementary system calls used for socket programming like socket(), bind(), connect(), listen(), accept(), send(), recv() and close(). It also discusses socket address structures and byte ordering routines for converting between big-endian and little-endian formats.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 74

I.

Introduction to Socket Programming


The socket interface was first provided with 4.1BSD system. The release supported the following communication protocols: 1. Unix domain 2. Internet domain (TCP/IP) 3. Xerox NS domain There are two types of interface provided by 4.3 BSD 1. Connection oriented protocol 2. Connection less protocol

Socket Addresses
Many of the BSD networking system calls require a pointer to a socket address structure as an argument. The definition of this structure is in <sys/socket.h> struct sockaddr { u_short sa_family; char sa_data[14]; };

/* address family: AF_xxx value*/ /* upto 14 bytes of protocol specific address*/

The contents of the 14 bytes of protocol-specific address are interpreted according to the type of address. For the Internet family, the following structures are defined in <netinet/in.h> struct in_addr { u_long s_addr; }; struct sockaddr_in { short sin_family; u_short sin_port; struct in_addr; char sin_zer[8]; };

/* 32bit net id/host id*/ /*network byte ordered*/

/*AF_INET*/ /*16bit port number*/ /* network byte ordered*/ /* 32bit net id/host id*/ /*network byte ordered*/ /* unused */

For the Xerox NS family, the following structures are defined in <netns/ns.h> union ns_host { u_char c_host[6]; /* hosted addr as six bytes*/ u_short s_host;/* hosted addr as three 16bit shorts*/ /* network byte ordered*/ }; union ns_net { u_char c_net[4]; u_short s_net[2]; }; struct ns_addr /* here is thw combined 12byte XNS address*/ { union ns_net x_net; /*4byte netid*/ union ns_host x_host; /*6byte hostid*/ u_short x_port; /*2byte port (XNX socket)*/ /*network byte ordered*/ }; struct sockaddr_ns { u_short sns_family; /*AF_NS*/ struct ns_addr sns_addr; /*the 12byte XNS address*/ char sns_zero[2]; /*unused*/ }; For the UNIX domain, the following structures are defined in <sys/un.h> struct sockaddr_un { short sun_family; /*AF_UNIX*/ char sun_path[108]; /*path name*/ }; A picture of these socket address structures is shown below struct sockaddr_in struct sockaddr_ns struct sockaddr_un Family Family Family 4-byte net ID 2-byte port Pathname (upto 108bytes) 6-byte host ID 4-byte net ID, host ID (unused) 2-byte port (unused)

/*netid as four bytes*/ /*netid as two 16bit shorts*/ /*network byte ordered*/

Elementary System Calls

Socket(): To do network I/O the first thing a process must do is call the socket system call, specifying the type of communication protocol desired(Internet TCP, Internet UDP, XNS, SPP, etc. ). Syntax: int socket(int family, int type,int proctocol); The family is one of AF_UNIX Unix internal protocols AF_INET Internet protocols AF_NS Xerox NS protocols AF_IMPLINK IMP Link Layer The AF_prefix stands for address family The socket type is one of the following: SOCK_STREAM SOCK_DGRAM SOCK_RAW SOCK_SEQPACKET SOCK_RDM

Stream socket Datagram socket Raw socket Sequenced packet socket Reliably delivered message socket (not implemented yet)

The protocol argument to the socket system call is typically set to 0 for most user applications. Family AF_INET AF_INET AF_INET AF_INET AF_NS AF_NS AF_NS AF_NS Type SOCK_DGRAM SOCK_STREAM SOCK_RAW SOCK_RAW SOCK_STREAM SOCK_SEQPACKET SOCK_RAW SOCK_RAW Protocol IPPROTO_UDP IPPROTO_TCP IPPROTO_ICMP IPPROTO_RAW NSPROTO_SPP NSPROTO_SPP NSPROTO_ERROR NSPROTO_RAW Actual protocol UDP TCP ICMP (raw) SPP SPP Error Protocol (raw)

The socket system call returns a small integer value, similar to a file descriptor and is called as socket descriptor or sockfd. Socketpair(): This is implemented only for the Unix domain int socketpair( int family, int type, int protocol, int sockvec[2]); This returns two socket descriptors, sockve[0] and sockvec[1], that are unnamed and connected. This is similar to the pipe system call, but socketpair returns a pair of socket descriptors, not file descriptors. Additionally, the two socket descriptors returned by socketpair are bi-directional, unlike pipes, which are unidirectional.

bind(): The bind system call assigns a name to an unnamed socket. #include<sys/types.h> #include<sys/socket.h> Syntax:int bind(int sockfd, struct sockaddr *myaddr, int addrlen); The second argument is a pointer to a protocol specific address and the third argument is the size of this address structure. There are three uses of bind 1. Servers register their well known address with the system. It tells the system this is my address and any messages received for this address are to be given to me. Both connectionoriented and connectionless servers need to do this before accepting client requests. 2. A Client can register a specific address for itself. 3. A connectionless client needs to assure that the system assigns it some unique address, so that the other end (the server) has a valid return address to send its responses to. This corresponds to making certain an envelope has a valid return address, if we expect to get a reply from the person we send the letter to. The bind system call fills in the local-addr and local-process elements of the association 5 tuple connect(): A client process connects a socket descriptor following the socket system call to establish a connection with a server. #include<sys/types.h> #include<sys/socket.h> Syntax: int connect(int sockfd, struct sockaddr *servaddr, int addrlen); For most connectionoriented protocols, the connect system call results in the actual establishment of a connection between the local system and the foreign system. Messages are typically exchanged between the two systems and specific parameters relating to the conversation might be agreed on. The client does not have to bind a local address before calling connect. The connection typically causes these four elements of the association 5tuple to be assigned: localaddress, local-process, foreign-process, foreign-addr, and foreign-process. listen(): This system call is used by a connectionoriented server to indicate that it is willing to receive connections. Syntax: int listen(int sockfd, int backlog); It is usually executed after both the socket and bind system calls, and immediately before the accept system call, The backlog argument specifies how many connection requests can

be queued by the system while it waits for the server to execute the accept system call. This argument is usually specified as 5, the maximum value currently allowed. The backlog argument refers to this queue of pending requests for connections. accept(): After a connection-oriented sever executes the listen system call described above, an actual connection from some client process is waited for by having the server execute the accept system call. #include<sys/types.h> #include<sys/socket.h> Syntax: int accept(int sockfd, struct sockaddr *peer, int *addrlen); accept takes the first connection request on the queue and creates another socket with the same properties as sockfd. If there are no connection requests pending, this call blocks the caller until one arrives. The peer and addrlen argument are used to return the address of the connected peer process (the client). addrlen is called a value-result argument: the caller sets its value before the system call stores a result in the variable. Often these value-result arguments are integers that the caller sets to the size of the buffer, with the system call changing this value on the return to the actual of data stored in the buffer. send, sendto, recv and recvfrom: These system calls are similar to the standard read and write system calls, but additional arguments are required #include<sys/types.h> #include<sys/socket.h> Syntax: int send(int sockfd, char *buff, int nbytes, int flags); int sendto(int sockfd, char *buff, int nbytes, int flags, struct sockaddr *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 *to, int addrlen); The first three arguments, sockfd, buff and nbytes to the four system calls are similar to the first three arguments for read and write. The to argument for sendto specifies the protocol-specific address of where the data is to be sent. This address is protocol-specific, its length must be specified by addrlen. The recvfrom system call fills in the protocol-specific address of who sent the data into from. The length of this address is also returned to the caller in addrlen. The final argument to sendto is an integer value, while the final argument to recvfrom is a pointer to an integer value. All four system calls return the length of the data that was written or read as the

value of the function. In the typical use of recvfrom, with a connectionless protocol, the return value is the length of the datagram that was received. close(): The normal Unix close system call is used to close a socket. Syntax: int close(int fd);

Byte Ordering Routines


Not all computers store the bytes that comprise a multibyte value in the same order. There are two ways to store multi byte values 1. Low order byte at the starting address known as Little endian Eg: A representation of 16-bit value in little endian notation High-order byte Low-order byte at addr A+1 at addr A 2. High order byte at the starting address known as Big endian Eg: A representation of 16-bit value in Big endian notain High-order byte Low-order byte at addr A at addr A+1 IBM 370, Motorola 68000, Pyramid uses Big endian. Intel 80x86(IBM PC), DEC VAX, DEC PDP -11 uses Little endian. The current machines use Little endian format but, all network protocols use Big endian format for 16-bit integers and 32-bit integers. The following four functions are used to perform the conversion from little endian to big endian which are defined in the following libraries. #include<sys/types.h> #include<netinet/in.h> u_long htonl (u_long hostlong); u_short htons (u_short hstshort); u_long ntohl (u_long netlong); u_short ntohs (u_short netshort); //convert host-to-network, long integer //convert host-to-network, short integer //convert network-to-host, long integer //convert network-to-host, short integer

These four functions are operated on unsigned integer values, although they work just as well on signed integers. A short integer occupies 16 bits and a long integer 32 bits.

Byte Operations

There are multibyte fields in the various socket address structures that need to be manipulated 4.3 BSD defines the following three routines that operate on user-defined byte strings. By user defined we mean they are not the standard C character strings (which are always terminated by a null byte). The user defined byte strings can have null bytes within them and these do not signify the end of the string. Instead, we must specify the length of each string as an argument to the function. bcopy (char *src, char *dest, int nbytes); bzero (char *dest, int nbytes); int bcmp (char *ptr1,char *ptr2, int nbytes); bcopy moves the specified number of bytes from the source to the destination. Note that the order of the two pointer arguments is different from the order used by the standard I/O strcpy function. The bzero function writes the specified number of null bytes to the specified destination. The bcmp compare two arbitary byte strings. The return value is zero if the two user defines byte strings are identical, otherwise its nonzero. These functions are usually to operate on socket address structures.

Address Conversion Routines


Internet address is usually written in the dotted decimal format, for eg: 172.16.0.1 The following functions convert between the dotted decimal format and an in_addr structure #include<sys/types.h> #include<netinet/in.h> #include<arpa/inet.h> unsigned long inet_addr (char *ptr); char *inet_ntoa (struct in_addr inaddr); The inet_addr converts a character string in dotted decimal notation to a 32-bit internet address. The inet_ntoa function does the reverse conversion.

Advanced Socket System Calls

readv and writev: The variants of the standard read and write system calls provide the ability of read into or write from noncontiguous buffers. #include<sys/types.h> #include<sys/uio.h> Syntax: int writev (int fd, struct iovec iov[], int iovcount); int readv (int fd, strcut iovec iov[], int iovcount);

Thes two system calls use the following structure that is defined in <sys/uio.h> struct iovec { caddr_t iov_base; int iov_len; };

// starting address of buffer // size of buffer in bytes

The writev system call writes the buffer specified by iov[0], iov[1], through iov[iovcount1]. The readv system call does the input equivalent. readv always fills one buffer (as specified by the iov_len value) before proceeding to the next buffer in the iov array. Both system calls return total bytes read or written. sendmsg and recvmsg: These two system calls are the most general of all the read write system calls. #include<sys/types.h> #include<sys/uio.h> Syntax: int sendmsg (int sockfd, struct msghdr msg[], int flags); int recvmsg (int sockfd, struct msghdr msg[], int flags);

These use the msghdr structure that is defined in <sys/socket.h> struct msghdr { caddr_t msg_name; int msg_namelen; struct iovec *msg_iov; int msg_iovlen; caddr_t msg_accrights int msg_accrightslen; };

//optional address //size of address //scatter/gather array //#element in msg_iov //access rights sent/recvd

getpeername(): This system call returns the name of the peer process that is connected to a given socket.

#include<sys/types.h> #include<sys/socket.h> Syntax: int getpeername(int sockfd, struct sockaddr *peer, int *addrlen); When we say that this system call returns the name of the peer process, we mean that it returns the foreign-addr and foreign-process elements of the 5-tuple associated with sockfd. Note that the final argument is a value-result argument. getsockname(): This system call returns the name associated with a socket. #include<sys/types.h> #include<sys/socket.h> Syntax: int getsockname(int sockfd, struct sockaddr *peer, int *addrlen); This call returns the local-addr and local-process elements of an association. As with the getpeername system call, the final argument is a value-result argument. getsockopt and setsockopt system calls These two system calls manipulate the option associated with a socket. These can modify the properties of a socket. shutdown(): The normal way to terminate a network connection is to call the close system call. Close normally attempts to deliver any data that is still to be sent. But the shutdown system call provides more control over a full duplex connection. Syntax: int shutdown(int sockfd, int howto);

If the howto argument is 0, no more data can be received on the socket. A value of 1 causes no more output to be allowed on the socket. A value of 2 causes both send and receives to be disallowed. Remember that a socket is usually a full-duplex communication path. The data flowing in one direction is logically independent of the data going in the other direction. This is why shutdown allows either direction to be closed independent of the other direction. select(): This is used when dealing with multiple descriptors.

Reserved ports

Every communicating process is identified by the TP layer with a 16-bit number called port. For well known services are provided on certain ports called reserved ports. 4.3 BSD supports the concept of reserved ports in both the Internet an XNS domains. In the Internet domain, any TCP or UDP port in the range 1 1023 is reserved, and in XNS domain ports in the range 1 2999 are reserved. A process is not allowed to bind a reserved port unless its effective user id is zero (the superuser) 4.3 BSD provide a library function that assigns a reserved TCP stream socket to its caller int rresvport (int *aport); This function creates an internet stream socket and binds a reserved port to the socket. The socket descriptor is returned as the value of the function unless an error occurs, in which case 0 1 is returned. The below table summarizes the assignment of ports in the Internet and XNS domains. Internet XNS Reserved ports 1 1023 1 2999 Ports automatically assigned by system 1024 5000 3000 65535 Ports assigned by rresvport() 512 1023 fcntl(): This system call affects an open file, referenced by the fd argument. #include<fcntl.h> int fcntl(int fd, int arg); ioctl(): This system call affects an open file, referenced by the fd argument. The intent of ioctl is to manipulate device options. #include<sys/ioctl.h> int ioctl(int fd, unsigned long request, char *arg); requests can be of four categories: file operations socket operations routing operations interface operations

II. Understanding Basic Commands

10

netstat:
netstat prints information about the Linux networking subsystem like network connections, routing tables, interface statistics, masquerade connections and multicast memberships i.e., network status. By default, netstat displays a list of open sockets. If you dont specify any address families, then the active sockets of all configured address families will be printed. Some options are: -a: shows the state of all sockets. -b: shows the addresses of protocol control blocks.

ifconfig:
ifconfig assign & configures network interface parameters. It must be used at boot time to define the network address of each interface present on a machine. Some options are: up: mark an interface up & happens automatically when setting first address on interface. down: marks an interface down. When an interface is marked down the system will not attempt to transmit messages through that interface.

ping:
ping-send ICMP ECHO_REQUEST packets to network hosts. Ping uses the ICMP protocols mandatory ECHO_REQUEST datagram to elicit the ICMP ECHO_RESPONSE from a host or gateway. ECHO_REQUEST datagram have an IC and ICMP leader followed by a struct timeval" and then an arbitrary number of "pad" byte used to fire out the packet.

arp:
arp-manipulate the system ARP cache arp-a[hostname] arp manipulates the kernel's ARP cache in many ways. The primary options are clearing an address mapping entry and manually setting up one. For debugging purposes, the arp program also allows a complete dump of the ARP cache.

telnet:
telnet-user interface to the TELNET protocol

11

The telnet command is used to communicate with another host using the TELNET protocol. If telnet is involved without the host argument, it enters command mode, indicated by the prompt (telnet>).In this mode, it accepts and executes the commands. If it is involved with argument, it performs an open command with those arguments.

tftp:
tftp-trivial file transfer program tftp[host] tftp is the user interface to the internet tftp which allows the users to transfer files to and from a remote machine.

ftp:
ftp-ARPANET file transfer program ftp[host] ftp is the user interface to the ARPANET standard file transfer protocol. This program allows user to transfer files to and from a remote network site.

III. Client Server Model

12

A server is a process that is waiting to be contacted by a client process so that the server can do something for the client. A client is a process who sends requests to the server. A typical scenario is as follows The server process is started on some computer system. It initializes itself, then goes to sleep waiting for a client process to contract it requesting some service. A Client process is started is started either on the same system or on another system that is connected to the servers system. Client processes are often initiated by an iterative user entering a command to a time sharing system. The client process sends a request across the network to the server requesting service of some form. The types of services that a server can provide are i. Return the time of the day to the client ii. Print a file on the printer to the client iii. Read or write a file on the servers system for the client iv. Allow the client to login to the servers system v. Execute a command for the client on the servers system. When the server process has finished providing the service to the client, the server goes back to sleep, waiting for the next client request.

Servers are of two types 1. Iterative Server An unthreaded connection-oriented server is said to be an iterative server. When the client request can be handled by the server in a known, short amount of time the server process handles the request itself. Eg: Time of Day service. 2. Concurrent Server A connection-oriented server can be threaded so that it can serve multiple clients concurrently/simultaneously. Such a server is said to be a concurrent server. When the amount of time to service a request depends on the request itself, the server typically handles it in a concurrent fashion.

Diagram showing the sequence of steps to be followed by the Connection-oriented Iterative server and client
13

Server socket()

bind()

listen()

Client socket()

accept()
Blocks from until connection client

Connection Request Message(Request)

connect() write() read() close()

Connection Established

read()

write() close()

Message(Reply)

Diagram showing the sequence of steps to be followed by the Connection-oriented Concurrent server and client
14

Server socket()

bind() Client

listen()

accept()
Blocks from until connection client

socket()

Connection Request

connect()

Connection Established

No (Parent Process)

fork()== 0

Yes (Child Process)

read()

Message(Request)

write()

write() close()

Message(Reply)

read() close()

15

Diagram showing the sequence of steps to be followed by the Connectionless Iterative server and client

Server

socket() Client socket() recvfrom() bind()


Blocks until message received Message(Request)

bind()

sendto()

sendto()

Message(Reply)

recvfrom()

16

Diagram showing the sequence of steps to be followed by the Connectionless Concurrent server and client

Server socket() Client bind() socket()

recvfrom()

bind()
Blocks until data received

sendto()

No

fork()== 0
(Parent Process)

Yes (Child Process)

recvfrom()

Message(Request)

recvfrom()

sendto()

Message(Reply)

sendto()

17

IV.

Algorithms and Programs

1. CONNECTION-ORIENTED ITERATIVE ECHO SERVER AND CLIENT IN UNIX DOMAIN


Algorithms
Sever 1. Create a socket in Unix domain using socket system call. 2. Assign the server address using bind system call. 3. The server process tells its willingness to accept connection request by executing listen system call. 4. Accept a connection request from the queue by executing accept system call. 5. Server process reads messages from client by executing read or recv system calls and echoes back to the client by executing send or write system calls. 6. step 5 is repeated until client process is terminated. 7. Close the socket using close system call. Client 1. Create a socket in Unix domain using socket system call. 2. Connect the client process by specifying the server address with connect system call. 3. If connect return 0 the send and receive message to and from the server by executing send or recv system calls. 4. Repeat 3 until there are no messages to send. 5. Close the socket using close system call.

18

/* Connection-oriented Iterative server in Unix Domain */


#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define SOCK_PATH "echo_socket" int main(void) { int s, s2, t, len; struct sockaddr_un local, remote; char str[100]; if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } local.sun_family = AF_UNIX; strcpy(local.sun_path, SOCK_PATH); unlink(local.sun_path); len = strlen(local.sun_path) + sizeof(local.sun_family); if (bind(s, (struct sockaddr *)&local, len) == -1) { perror("bind"); exit(1); } if (listen(s, 5) == -1) { perror("listen"); exit(1); } for(;;) { int done, n; printf("Waiting for a connection...\n"); t = sizeof(remote); if ((s2 = accept(s, (struct sockaddr *)&remote, &t)) == -1) { perror("accept");

19

exit(1); } printf("Connected.\n"); done = 0; do { n = recv(s2, str, 100, 0); if (n <= 0) { if (n < 0) perror("recv"); done = 1; } if (!done) if (send(s2, str, n, 0) < 0) { perror("send"); done = 1; } } while (!done); close(s2); } return 0; }

/*Connection-oriented Client in Unix Domain*/


#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define SOCK_PATH "echo_socket" int main(void) { int s, t, len; struct sockaddr_un remote; char str[100]; if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {

20

perror("socket"); exit(1); } printf("Trying to connect...\n"); remote.sun_family = AF_UNIX; strcpy(remote.sun_path, SOCK_PATH); len = strlen(remote.sun_path) + sizeof(remote.sun_family); if (connect(s, (struct sockaddr *)&remote, len) == -1) { perror("connect"); exit(1); } printf("Connected.\n"); while(printf("> "), fgets(str, 100, stdin), !feof(stdin)) { if (send(s, str, strlen(str), 0) == -1) { perror("send"); exit(1); } if ((t=recv(s, str, 100, 0)) > 0) { str[t] = '\0'; printf("echo> %s", str); } else { if (t < 0) perror("recv"); else printf("Server closed connection\n"); exit(1); } } close(s); return 0; }

21

OUTPUT
Server $cc server.c o s $./s Waiting for a connection... Connected Client $cc client.c o c $./c Trying to connect Connected >hello echo>hello

22

2. CONNECTION-ORIENTED ITERATIVE ECHO SERVER AND CLIENT IN INTERNET DOMAIN


Algorithms
Server 1. Create a socket in internet domain and the bind with the server socket address by using socket and bind system calls. 2. Open a passive connection to table the connection request from client by using listen call. 3. Take the connection request from the client, establish a connection to server using accept. 4. A request is sent to client for the connection to be established and message to be displayed. 5. Release the connection using close system call. Client : 1. Create a socket in the internet domain using socket system call. 2. Establish connection with the server by specifying the servers address using connect. 3. Release the connection by using close.

23

/* Program: Connection oriented iterative echo server in internet domain */


#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc,char * argv[]) { int s, s2, t, len; struct sockaddr_in local, remote; char str[100]; if( (s=socket(AF_INET,SOCK_STREAM,0)) == -1 ) { perror("socket error"); exit(1); } bzero((char*)&local,sizeof(local)); local.sin_family = AF_INET; local.sin_port = htons(atoi(argv[1])); local.sin_addr.s_addr = htonl(INADDR_ANY); if( bind(s,(struct sockaddr *)&local,sizeof(local)) == -1 ) { perror("bind error"); exit(1); } if( listen(s,5) == -1 ) { perror("listen error"); exit(1); } for( ; ; ) { int done, n; printf("Waiting for a connection...\n"); t = sizeof(remote); if( (s2=accept(s,(struct sockaddr *)&remote,&t)) == -1 ) { perror("accept error"); exit(1); } printf("Connected.\n"); done = 0; do { n = recv(s2,str,100,0);

24

if( n <= 0 ) { if( n < 0 ) perror("recv error"); done = 1; } if( !done ) if( send(s2,str,n,0) < 0 ) { perror("send error"); done = 1; } }while(!done); close(s2); }/*end for loop*/ return 0; }

/* Program: Connection oriented iterative echo client in internet domain */


#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc, char *argv[ ]) { int s, t, len; struct sockaddr_in remote; char str[100]; if( argc != 3 ) { printf("Invalid server address\n"); exit(0); } if( (s=socket(AF_INET,SOCK_STREAM,0)) == -1 ) { perror("socket error"); exit(1); } printf("%d\n",s); printf("Trying to connect %s...\n",argv[0]); bzero((char *)&remote, sizeof(remote)); remote.sin_family = AF_INET; remote.sin_port = htons(atoi(argv[2])); remote.sin_addr.s_addr = inet_addr(argv[1]);

25

if( connect(s,(struct sockaddr *)&remote, sizeof(remote)) == -1 ) { perror("connect"); exit(1); } printf("connected\n"); while(printf(">"), fgets(str,100,stdin), !feof(stdin)) { if( send(s,str,strlen(str),0) == -1 ) { perror("send"); exit(1); } if( t=recv(s,str,100,0) > 0 ) { printf("Echo > %s",str); } else { if( t<0 ) perror("recv"); else printf("server closed connection\n"); exit(1); } } close(s); return 0; }

OUTPUT
Server $ gcc coies.c $ ./a.out 1234 Waiting for a connection... Connected. Client $ gcc coiec.c -o cl $ ./cl 172.16.0.51 1234 Trying to connect ./cl... connected >Hello world Echo > Hello world >

26

3. CONNECTION-ORIENTED CONCURRENT ECHO SERVER AND CLIENT IN INTERNET DOMAIN


Algorithms
Server 1. Create a socket in internet domain and the bind with the server socket address by using socket and bind system calls. 2. Open a passive connection to table the connection request from client by using listen call. 3. Take the connection request from the client, establish a connection to server using accept. 4. A request is sent to client for the connection to be established and message to be displayed. 5. Release the connection using close system call. Client 1. Create a socket in the internet domain using socket system call. 2. Establish connection with the server by specifying the servers address using connect. 3. After the connection is established with the server, a message is sent to it. 4. Release the connection by using close.

27

/* Program: Connection Oriented Concurrent Echo Server using Internet domain*/


#include<stdio.h> #include<stdlib.h> #include<strings.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc, char * argv[ ]) { int s1, s2, t, len, cp; struct sockaddr_in local, remote; char str[100]; s1=socket(AF_INET,SOCK_STREAM,0); if( s1 == -1 ) { perror("socket"); exit(1); } printf("\n%d",s1); bzero((char *)&local,sizeof(local)); local.sin_family = AF_INET; local.sin_port = htons( atoi( argv[1] ) ); local.sin_addr.s_addr = inet_addr("172.16.0.51"); if(bind(s1,(struct sockaddr*)&local,sizeof(local))==-1) { perror("bind"); exit(1); } if(listen(s1,5)==-1) { perror("listen"); exit(1); } for( ; ; ) { int done,n; printf("waiting for a connection...\n"); t = sizeof(remote); s2 = accept(s1,(struct sockaddr*)&remote,&t); if(s2==-1) { perror("accept"); exit(1); } printf("connected"); if((cp=fork())<0) { perror("fork"); exit(1); }

28

else if(cp==0) { close(s1); done=0; } do { n = recv(s2,str,100,0); printf(" %s\n",str); if(n<=0) { if(n<0) perror("recv"); done = 1; } if(!done) { if(send(s2,str,n,0)<0) { perror("send"); done = 1; } } }while( !done ); exit( 0 ); close( s2 ); } return 0; }

/*Program: Connection Oriented Concurrent Echo Client using Internet domain*/


#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc, char *argv[]) { int s,t,len,a; struct sockaddr_in remote; char str[100]; if(argc!=3)

29

{ perror("invalid server address"); exit(0); } if((s=socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); exit(1); } printf("\n%d",s); printf("\ntrying to connect to %s...\n",argv[0]); bzero((char *)&remote, sizeof(remote)); remote.sin_family = AF_INET; remote.sin_port = htons(atoi(argv[2])); remote.sin_addr.s_addr =inet_addr(argv[1]); a = connect(s,(struct sockaddr *)&remote,sizeof(remote)); if( a == -1 ) { perror("connect"); exit(1); } printf("connected.\n"); while(printf(">"),fgets(str,100,stdin),!feof(stdin)) { if( send(s,str,strlen(str),0)== -1) { perror("send"); exit(1); } if(t=recv(s,str,100,0)>0) printf("echo> %s\n",str); else { if( t < 0 ) perror("recv"); else printf("server closed connection\n"); exit(1); } } close( s ); return 0; }

30

OUTPUT
Server $ gcc coces.c $ ./a.out 7890 waiting for a connection... connected CBIT IT Client $ gcc cocec.c -o cl $ ./cl 172.16.0.51 7890 trying to connect to ./cl... connected. >CBIT echo> CBIT >IT echo>IT

31

4. CONNECTIONLESS ITERATIVE ECHO SERVER AND CLIENT IN INTERNET DOMAIN


Algorithms
Server 1. Create a socket in internet domain and the bind with the server socket address by using socket and bind system calls. 2. The message is received from the client and it is displayed on the client terminal using recvfrom() system call. 3. The message is displayed on the server terminal. Client 1. Create a socket in the internet domain by using socket system call. 2. The message is sent to the server by using the sendto() system call. 3. If the server is closes its connection before the message was sent, then the server closed connection error will be displayed on the server side.

/* Program: Connectionless Iterative Echo Server using Internet domain */


#include<stdio.h> #include<stdlib.h> #include<strings.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc, char * argv[ ]) { int s, t; struct sockaddr_in local, remote; char str[100]; if( argc != 2 ) { perror("Usage: server <port>"); exit(0); } if( (s=socket(AF_INET,SOCK_DGRAM,0)) == -1 ) { perror("socket"); exit(1); } bzero( (char *)&local, sizeof( local ) ); local.sin_family = AF_INET; local.sin_port = htons( atoi( argv[1] )); local.sin_addr.s_addr =inet_addr("172.16.0.51");

32

if( bind(s,(struct sockaddr *)&local, sizeof(local)) == -1 ) { perror("bind"); exit(1); } t = sizeof(remote); memset(str,0,100); for( ; ; ) { int n; while( n=recvfrom(s, str,100 ,0, (struct sockaddr *)&remote, &t) > 0) { printf("%s\n",str); if( sendto(s,str,n,0,(struct sockaddr *)&remote,sizeof(remote)) < 0 ) { perror("sendto"); } memset(str, 0, 100); } if( n < 0 ) { perror("recvfrom"); exit(0); } } return 0; }

/* Program: Connection less iterative echo client using Internet domain*/


#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc, char * argv[]) { int s, t, n; struct sockaddr_in remote; char str[100]; if( argc != 2 ) { perror("Usage: client <server address> <port>"); exit(0); } if( (s=socket(AF_INET, SOCK_DGRAM,0)) == -1 ) { perror("socket"); exit(1); } bzero( (char *)&remote, sizeof(remote) );

33

remote.sin_family = AF_INET; remote.sin_port = htons( (short)atoi( argv[1] ) ); remote.sin_addr.s_addr = inet_addr("172.16.0.51"); t = sizeof(remote); while( printf(">"), fgets(str,100,stdin), !feof(stdin) ) { if( sendto(s,str,strlen(str),0,(struct sockaddr*)&remote,sizeof(remote)) <0 ) { perror("sendto"); exit(1); } if( (n=recvfrom(s,str,100,0,(struct sockaddr *)&remote, &t)) > 0 ) { printf("echo> %s\n",str); } else { if( n < 0 ) perror("recvfrom"); else printf("server closed connection\n"); } memset( str, 0, 100 ); } return 0; }

OUTPUT
Server $ gcc clies.c $ ./a.out 5454 CBIT WORLD Client $ gcc cliec.c -o cl $ ./cl 5454 >CBIT WORLD echo>CBIT WORLD

34

5. CONNECTIONLESS CONCURRENT ECHO SERVER AND CLIENT IN INTERNET DOMAIN


Algorithms
Server 1. Create a socket in internet domain and the bind with the server socket address by using socket and bind system calls. 2. The message is received from the client and it is displayed on the client terminal using recvfrom() system call. 3. The message is displayed on the server terminal. Client 1. Create a socket in the internet domain by using socket system call. 2. The message is sent to the server by using the sendto() system call. 3. If the server is closes its connection before the message was sent, then the server closed connection error will be displayed on the server side.

/* Program: Connectionless Concurrent Echo Server using Internet domain */


#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc, char * argv[ ]) { int s, t, n, cp; struct sockaddr_in local, remote; char str[100]; if( argc != 2 ) { perror("Usage: server <port>"); exit(0); } if( (s=socket(AF_INET,SOCK_DGRAM,0)) == -1 ) { perror("socket"); exit(1); } bzero( (char *)&local, sizeof( local ) ); local.sin_family = AF_INET; local.sin_port = htons( (short)atoi( argv[1] )); 35

local.sin_addr.s_addr = htonl( INADDR_ANY ); if( bind(s,(struct sockaddr *)&local, sizeof(local)) == -1 ) { perror("bind"); exit(1); } t = sizeof(remote); memset(str,0,100); for( ; ; ) { while((n=recvfrom( s, str, 100, 0, (struct sockaddr *)&remote, &t))>0 ) { if( n < 0 ) { perror("recvfrom"); exit(1); } printf("-%s\n",str); if( ( cp=fork() ) == 0 ) { while( 1 ) { if( sendto(s,str,n,0,(struct sockaddr *)&remote,sizeof(remote)) < 0 ) { perror("sendto"); break; } memset( str, 0, 100 ); n = recvfrom( s, str,100, 0, (struct sockaddr *)&remote, &t ); if( n < 0 ) { perror("recvfrom"); break; } } } else if( cp < 0 ) { perror("fork"); exit(1); } } } return 0; }

36

/* Program: Connectionless Concurrent Echo Client using Internet domain*/


#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc, char * argv[]) { int s, t, n; struct sockaddr_in remote; char str[100]; if( argc != 2 ) { perror("Usage: client <server address> <port>"); exit(0); } if( (s=socket(AF_INET, SOCK_DGRAM,0)) == -1 ) { perror("socket"); exit(1); } bzero( (char *)&remote, sizeof(remote) ); remote.sin_family = AF_INET; remote.sin_port = htons( (short)atoi( argv[1] ) ); remote.sin_addr.s_addr = inet_addr("172.16.0.51"); t = sizeof(remote); while( printf(">"), fgets(str,100,stdin), !feof(stdin) ) { if( (sendto(s,str,100,0,(struct sockaddr *)&remote,sizeof(remote)))< 0 ) { perror("sendto"); exit(1); } if( (n=recvfrom(s,str,100,0,(struct sockaddr *)&remote, &t)) > 0 ) { printf("echo> %s\n",str); } else { if( n < 0 ) perror("recvfrom"); else printf("server closed connection\n"); exit(1); } memset( str, 0, 100 ); } return 0; }

37

OUTPUT
Server $ gcc clces.c $ ./a.out 3434 -IT CBIT Client $ gcc clcec.c -o cl $ ./cl 3434 >IT CBIT echo> IT CBIT

38

6. CONNECTION-ORIENTED ITERATIVE TIME SERVER AND CLIENT IN INTERNET DOMAIN


Algorithms
Server 1. Creates a socket in the internet domain and binds with the servers socket address. 2. Opens a passive connection to take the connection request from the clients. 3. Take the connection request from the clients & establish connection. 4. Compute the system time and send the same to the client. 5. Release the connection. Client 1. Creates a socket in the internet domain. 2. Establish a connection with the server by specifying the server address. 3. After the connection is established, read the time & display it on the terminal. 4. Release the connection.

/* Program: Connection oriented iterative time service server */


#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<time.h> int main(int argc, char *argv[]) { int ls,cs; struct sockaddr_in servaddr; char buffer[1024]; time_t ct; if( argc != 2 ) { perror("Usage: server <port>"); exit(0); } if( (ls=socket(AF_INET,SOCK_STREAM,0)) == -1 ) { perror("socket"); exit(1); } bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons((short)atoi(argv[1])); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 39

if( bind(ls,(struct sockaddr *)&servaddr, sizeof(servaddr)) == -1 ) { perror("bind"); exit(1); } if( listen(ls,5) < 0 ) { perror("listen error"); exit(1); } while(1) { if(cs=accept(ls,NULL,NULL)<0) { perror("accept"); exit(1); } ct = time(NULL); sprintf(buffer,"%s\n",ctime(&ct)); write(cs,buffer,strlen(buffer)); close(cs); } return 0; }

/* Program: Connection oriented iterative time service client */


#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<time.h> int main(int argc, char *argv[]) { int n,cs; struct sockaddr_in servaddr; char buffer[1024]; time_t ct; if( argc != 2 ) { perror("Usage: server <port>"); exit(0); } if( (cs=socket(AF_INET,SOCK_STREAM,0)) == -1 ) { perror("socket"); exit(1); } bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons((short)atoi(argv[1]));

40

servaddr.sin_addr.s_addr = inet_addr("172.16.0.51"); if( connect(cs,(struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 ) { perror("connect"); exit(1); } printf("current time is: "); while((n=read(cs,buffer,1024))>0) { buffer[n] = '\0'; fputs(buffer,stdout); } if( n < 0 ) { perror("read"); exit(1); } return 0; }

OUTPUT
Server $ gcc timeserver.c $ ./a.out 6565 Tue Feb 17 15:07:42 2009 Client $ gcc timeclient.c -o tcl $ ./tcl 6565 current time is: Tue Feb 17 15:09:19 2009

41

7. CONNECTIONLESS INTERATIVE TIME SERVER AND CLIENT IN INTERNET DOMAIN


Algorithms
Server 1. Creates a socket in the internet domain and binds with the servers socket address. 2. The message is received from the client by using recvfrom() system call. 3. The received message is displayed on the servers terminal. Client 1. Creates a socket in the internet domain. 2. The message is sent to the server by using sendto() system call and is displayed on the clients terminal.

/* Program: Connection less iterative time service server */


#include<stdio.h> #include<stdlib.h> #include<sys/socket.h> #include<sys/types.h> #include<string.h> #include<netinet/in.h> #include<errno.h> #include<time.h> int main(int argc,char*argv[]) { int s,t; struct sockaddr_in servaddr,cliaddr; char buffer[1024]; time_t ct; if(argc!=2) { printf("\nusage:client<server-addr><port>"); exit(0); } if((s=socket(AF_INET,SOCK_DGRAM,0))<0) { perror("socket"); exit(0); } bzero((char*)&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(atoi(argv[1])); servaddr.sin_addr.s_addr=inet_addr("172.16.0.51"); if(bind(s,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) { perror("bind"); exit(0); } t=sizeof(servaddr); while(1) { 42

if(recvfrom(s,buffer,1024,0,(struct sockaddr*)&cliaddr,&t)<0) { perror("recvfrom"); exit(0); } ct=time(NULL); sprintf(buffer,"%s",ctime(&ct)); if(sendto(s,buffer,strlen(buffer),0,(struct sockaddr*)&cliaddr,sizeof(cliaddr))<0) { perror("send to"); exit(0); } } close(s); return 0; }

/*Program: Connection less iterative time service client*/


#include<stdio.h> #include<stdlib.h> #include<sys/socket.h> #include<sys/types.h> #include<string.h> #include<netinet/in.h> #include<errno.h> #include<time.h> int main(int argc,char*argv[]) { int n,s,t; struct sockaddr_in servaddr,local; char buffer[1024]; time_t ct; if(argc!=2) { printf("usage:client<server-addr><port>"); exit(0); } if((s=socket(AF_INET,SOCK_DGRAM,0))<0) { perror("socket"); exit(0); } bzero((char *)&local,sizeof(local)); local.sin_family=AF_INET; local.sin_port=htons(3222); local.sin_addr.s_addr=inet_addr("172.16.0.51"); if(bind(s,(struct sockaddr *)&local,sizeof(local))==-1) { perror("bind"); exit(1); } bzero((char*)&servaddr,sizeof(servaddr)); servaddr.sin_family=AF_INET; servaddr.sin_port=htons(atoi(argv[1])); servaddr.sin_addr.s_addr=inet_addr("172.16.0.51"); strcpy(buffer,"TIME");

43

if(sendto(s,buffer,sizeof(buffer),0,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) { perror("send to"); exit(0); } t=sizeof(servaddr); printf("the current time is"); if((n=recvfrom(s,buffer,1024,0,(struct sockaddr*)&servaddr,&t))>0) { buffer[n]='\0'; fputs(buffer,stdout); } if(n<0) { perror("read from"); exit(0); } return 0; }

OUTPUT
Server $ gcc tsudp.c $ ./a.out 5555 Client $ gcc tcudp.c -o cl $ ./cl 5555 the current time is: Tue Mar 3 15:12:39 2009

44

8. REMOTE COMMAND EXECUTION SERVER AND CLIENT IN INTERNET DOMAIN


Algorithms
Server 1. Create a socket in the internet domain and then bind it with the server socket address. 2. Open a passive connection to take the connection request from the clients. 3. Take the connection request from the client and establish a connection to the server. 4. Receive the command from the client and print the corresponding output. 5. Release the connection using close(). Client 1. Create a socket in the internet domain. 2. Establish a connection with the server specifying the address. 3. Once the connection is established, write the command or Q for quit and send it to server.

/*Program: Remote Command Execution server*/


#include<stdio.h> #include<stdlib> #include<sys/types.h> #include<sys/socket.h> #include<string.h> #include<netinet/in.h> #define MAX 1024 int main(int argc, char *argv[]) { int sockfd,addrlen,new,n; char buff1[MAX]; struct sockaddr_in serv_addr,peer; sockfd=socket(AF_INET,SOCK_STREAM,0); if( sockfd == -1) { perror("Error in Server"); exit(1); } serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(atoi(argv[1])); serv_addr.sin_addr.s_addr=inet_addr("172.16.0.51"); if( bind(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0 ) { perror("Error in Server "); exit(1); }

45

if( listen(sockfd,5) < 0 ) { perror("Error in Server "); exit(1); } for( ; ; ) { if( (new=accept(sockfd,(struct sockaddr *)&peer,&addrlen)) < 0 ) { perror("Error in Server"); exit(1); } if( (fork()) == 0 ) { for( ; ; ) { if( (n=read(new,buff1,MAX)) < 0 ) { perror("Error in Server "); exit(1); } if( n == 0 ) break; buff1[n]='\0'; // fflush(stdout); if( !strcmp("exit",buff1) ) { printf("\a\a server is exiting"); exit(1); } close(1); if(dup(new)<0) printf("\nserver: dup system call failure"); fflush(stdout); system(buff1); if((write(new,"\n",1))<0) perror("write error"); } //exit(0); } close(new); } }

/*Program: Remote Command Execution client*/

46

#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include<stdlib.h> #define MAX 1024 int main(int argc,char *argv[]) { int sockfd,addr_len,n; char buff1[MAX],buff2[MAX]; struct sockaddr_in serv_addr; sockfd=socket(AF_INET,SOCK_STREAM,0); if(sockfd==-1) { perror("Error in Client:"); exit(1); } serv_addr.sin_family=AF_INET; serv_addr.sin_port=htons(atoi(argv[1])); serv_addr.sin_addr.s_addr=inet_addr("172.16.0.51"); if((connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)))<0) { perror("Error in Client: "); exit(1); } fflush(stdout); for( ; ; ) { printf("\nEnter the command string: "); fflush(stdout); if( (n=read(0,buff1,MAX+1)) < 0 ) { perror("Error in Client: "); exit(1); } buff1[n]='\0'; if( (n=write(sockfd,buff1,n+1)) < 0 ) perror("Error in Client: "); if( (bcmp("exit",buff1,4)) == 0 ) { printf("\a\a Client is exiting...\n"); exit(1); } sleep(1); if((n=read(sockfd,buff2,MAX))<0) { perror("Error in Client: "); exit(1); } buff2[n]='\0'; if(write(1,buff2,n+1)<0) perror("Client:Write by client ot the screen");

47

} return 0; }

OUTPUT
Server $ gcc rcs.c $ ./a.out 8989 Client $ gcc rcc.c -o cl $ ./cl 8989 Enter the command string: dir a.out clces.c cocec.c corcec.c echo_socket.c server.c timeclient.c bind.c cliec.c coces.c corces.c ecl socket.c timeserver.c cl client.c coiec.c echoclient.c rcc.c tcl clcec.c clies.c coies.c echo_socket rcs.c tcp.c Enter the command string:

9. getpeername() SYSTEM CALL EXAMPLE


48

Algorithms
Server 1. Create a socket in the internet domain and binds it with the server socket address. 2. Opens a passive connection to take the connection request from the clients. 3. Take the connection request from the clients when they arrives and establish a connection. Client 1. Create a socket in the internet domain and actively opens a connection. 2. Establish the connection with the server specifying the server address. 3. After the connection is established call the function getpeername() to get the peers name. 4. Displays the port and IP address.

Flow Chart
Create a socket using socket() system call

Connect the socket to any host on port 80 using connect() system call

Call getpeername() system call to get peer host details

Display the peer host details

Close the socket using close() system call

/* Program: implementing getpeername server */


49

#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main( int argc, char * argv[] ) { int s, s2, t, len; struct sockaddr_in local,rem; char str[100]; s = socket(AF_INET,SOCK_STREAM,0); if(s==-1) { perror("socket"); exit(1); } bzero((char*)&local,sizeof(local)); local.sin_family=AF_INET; local.sin_port=htons(atoi(argv[1])); local.sin_addr.s_addr=inet_addr("172.16.0.51"); if(bind(s,(struct sockaddr*)&local,sizeof(local))==-1) { perror("bind"); exit(1); } if(listen(s,5)==-1) { perror("listen"); exit(1); } for(;;) { int done,n; printf("waiting for a connection....\n"); t=sizeof(rem); s2=accept(s,(struct sockaddr*)&rem,&t); if(s2==-1) { perror("accept"); exit(1); } } close(s2); return 0; }

/* Program: implementing getpeername client */

50

#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc,char *argv[]) { int s; struct sockaddr_in server,addr; socklen_t len; s = socket( AF_INET, SOCK_STREAM, 0 ); if( s == -1 ) { perror("socket"); exit(1); } server.sin_family = AF_INET; inet_aton("172.16.0.51",&server.sin_addr); server.sin_port = htons( atoi(argv[1]) ); if( connect(s,(struct sockaddr *)&server,sizeof(server)) < 0 ) { perror("connect"); exit(0); } len = sizeof(addr); getpeername(s,(struct sockaddr *)&addr,&len); printf("peer IP address:%s\n",inet_ntoa(addr.sin_addr)); printf("peer port:%d\n",ntohs(addr.sin_port)); return 0; }

OUTPUT
Server $ gcc getpeernameserver.c $ ./a.out 7676 waiting for a connection.... Client $ gcc getpeernameclient.c $ ./a.out 7676 peer IP address: 172.16.0.51 peer port: 7676

10. select() SYSTEM CALL EXAMPLE


51

Description
This system call can be used when we are dealing with multiple descriptors. Consider a process that needs input from more than one source. An actual example is the 43BSD printer spooler. It opens two sockets. One is UNIX stream socket to receive the requests from the process on the same host and the other TCP socket to receive the print requests from the processes on the other hosts. Since it doesnt know when the requests arrive from both the sockets, it cant read on those sockets. We can handle this multiplexing of different i/o channels using this select() system call.

Flow Chart

Create a variable for timeval structure and initialize it

Call select() system call with timeval structure variable

/* Program: implementing select() system call */


52

#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<sys/types.h> #include<sys/time.h> int main(int argc, char *argv[]) { static struct timeval timeout; if(argc!=3) { printf("\n Usage : %s <seconds> <microseconds>",argv[0]); exit(0); } timeout.tv_sec=atol(argv[1]); timeout.tv_usec=atol(argv[2]); if(select(0,(fd_set *) 0,(fd_set *) 0,(fd_set *) 0,&timeout)<0) { perror("select"); exit(0); } return 0; }

OUTPUT
$ vi select.c $ ./a.out 10 06

11. getsockopt() AND setsockopt() SYSTEM CALLS EXAMPLE


53

Description
This program prints the TCP maximum segment size associated with a socket. It also sets the send buffer size of a socket and prints that modified size.

Flow Chart

Create a socket using socket() system call Call getsockopt() system call to get the socket option for TCP max. segment and display it

Call setsockopt() system call to set the socket option for socket send buffer size Call getsockopt() system call to get the socket option for socket send buffer size and display it Close the socket using close() system call

/* Program: Implementing setsockopt() & getsockopt() */


54

#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #include<netinet/tcp.h> int main() { int sockfd,maxseg,sendbuff,optlen; sockfd = socket(AF_INET,SOCK_STREAM,0); if( sockfd < 0 ) { perror("socket"); exit(0); } optlen=sizeof(maxseg); if( getsockopt(sockfd,IPPROTO_TCP,TCP_MAXSEG,(char *)&maxseg,&optlen) < 0 ) { perror("getsockopt1"); exit(0); } printf("\n TCP maxseg=%d",maxseg); sendbuff=12324; if(setsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,(char *)&sendbuff,sizeof(sendbuff))<0) { perror("setsockopt"); exit(0); } optlen=sizeof(sendbuff); if(getsockopt(sockfd,SOL_SOCKET,SO_SNDBUF,(char *)&sendbuff,&optlen)<0) { perror("getsockopt2"); exit(0); } printf("\n Send Buffer size=%d",sendbuff); return 0; }

OUTPUT
$ gcc getsetsockopt.c $ ./a.out TCP maxseg=536 Send Buffer size=24648

12. ASYNCHRONOUS I/O EXAMPLE


55

Description
This program reads from the standard input and writes to the standard output by using asynchronous I/O.

Flow Chart

Call signal() system call to handle IO signals

Call fcntl() system call for setting process id or process group id

Call fcntl() system call for enabling Asynchronous IO Read data from keyboard using Asynchronous IO

Write the data to output screen using Asynchronous IO

//Program
#include <signal.h> #include <fcntl.h> #define BUFFSIZE 4096 int sigflag; main()

56

{ int n; char buff[BUFFSIZE]; int sigio_func(); signal(SIGIO,sigio_func); if(fcntl(0,F_SETOWN,getpid())<0) { perror("F_SETOWN"); exit(0); } if(fcntl(0,F_SETFL,FASYNC)<0) { perror("F_SETFL FASYNC"); exit(0); } for(;;) { sigblock(sigmask(SIGIO)); while(sigflag==0) sigpause(0); if((n=read(0,buff,BUFFSIZE))>0) { if(write(1,buff,n)!=n) perror("write"); } else if(n<0) perror("read"); else if(n==0) exit(0); sigflag=0; sigsetmask(0); } } int sigio_func() { sigflag=1; }

OUTPUT
$cc asyncio.c $./a.out hello hello

13. NON-BLOCKING I/O EXAMPLE


57

Description
This program reads from the standard input and writes to the standard output by using nonblocking I/O.

Flow Chart

Call fcntl() system call for enabling Nonblocking IO Read data from keyboard using Non-blocking IO

Write the data to output screen using Non-blocking IO

//Program
#include <fcntl.h> #include <errno.h> #include<stdio.h> #define BUFFSIZE 100 main() { int n; char buff[BUFFSIZE]; if(fcntl(0,F_SETFL,FNDELAY)<0) { perror("Nonblocking failed"); exit(0); }

while(1)

58

{ while((n=read(0,buff,BUFFSIZE))<0) { if(errno!=EWOULDBLOCK) break; } fflush(stdout); if(write(1,buff,n)<0) { perror("write"); break; } } }

OUTPUT
$cc nonblockio.c $./a.out hello hello

14. CONCURRENT CHAT SERVER AND CLIENT


59

Algorithms
Server 6. Create a socket in internet domain and the bind with the server socket address by using socket and bind system calls. 7. Open a passive connection to table the connection request from client by using listen call. 8. Take the connection request from the client, establish a connection to server using accept. 9. A request is sent to client for the connection to be established and message to be displayed. 10. Release the connection using close system call. Client 5. Create a socket in the internet domain using socket system call. 6. Establish connection with the server by specifying the servers address using connect. 7. After the connection is established with the server, a message is sent to it. 8. Release the connection by using close.

/* Program: Chat server */


#include<stdio.h> #include<sys/types.h> #include<sys/socket.h> #include<string.h> #include<netinet/in.h> #include<stdlib.h> #include<errno.h> #define MAX 80 int main(int argc,char *argv[]) { int s,s2,t,len,cp,i,j,n; char str[100]; struct sockaddr_in local,rem; s = socket(AF_INET,SOCK_STREAM,0); if( s == -1 ) { perror("socket");exit(1); } bzero((char*)&local,sizeof(local)); local.sin_family = AF_INET; 60

local.sin_port = htons(atoi(argv[1])); local.sin_addr.s_addr = htonl(INADDR_ANY); if( bind(s,(struct sockaddr*)&local,sizeof(local)) == -1) { perror("bind"); exit(1); } if( listen(s,5) == -1) { perror("listen"); exit(1); } for( ; ; ) { t = sizeof(rem); s2 = accept( s, (struct sockaddr *)&rem, &t ); if( s2 == -1 ) { perror("accept"); exit(1); } cp = fork(); if( cp < 0 ) { perror("fork error"); exit(1); } if( cp == 0 ) { close(s); printf("s=%d s2=%d t=%d\n",s,s2,t); for( j=0; j<5; ++j) { n = recv(s2,str,100,0); str[n] = '\0'; printf("client:%s\n>",str); write(1,"server>",7); n = read(0,&str,MAX); send(s2,&str,n,0); } close(s2); } } close(s); return 0; }

/* Program: Chat client */


61

#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #define max 80 int main(int argc,char *argv[]) { int s,t,len,a,i,n; struct sockaddr_in rem; char str[100]; if( argc != 2 ) { printf("\n invalid server address"); exit(0); } s = socket(AF_INET,SOCK_STREAM,0); if( s == -1) { perror("socket"); exit(1); } rem.sin_family=AF_INET; rem.sin_port=htons(atoi(argv[1])); rem.sin_addr.s_addr=inet_addr("172.16.0.51"); a = connect(s,(struct sockaddr *)&rem,sizeof(rem)); if( a == -1) { perror("not connect"); exit(1); } printf("connected\n"); for( i=0; i<5; ++i) { write(1,"client>",7); n = read(0,&str,max); send(s,str,n,0); write(1,"server:",7); n = recv(s,str,100,0); write(1,&str,n); } close(s); return 0; }

OUTPUT
62

Server $ gcc chatserver.c $ ./a.out 9898 s=3 s2=4 t=16 client: Hi server>Hello

Client $ gcc chatclient.c -o cl $ ./cl 9898 connected client>Hi server: Hello client>

63

15. PREFORKED CONNECTION-ORIENTED ECHO SERVER AND CLIENT IN INTERNET DOMAIN


Algorithms
Server The server program repeatedly listens for incoming client requests (messages). When a client requests the server for a connection, the server accepts the connection and echoes the same received message back to the client. Here the server processes the client requests simultaneously (concurrently). The concurrency is achieved by initially forking some fixed number of child processes and assigning them to the clients on demand (when client request arrives). This echoing process is repetitive. Client The client makes a connection request to the server. If the connection is made successfully, it reads a message from standard input and sends it to the server. When the client receives the echoed message, it prints it on its standard output. The server and client programs are implemented in internet domain using connectionoriented communication.

/* Program: preforked server */


#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> static int nchilds=4; static pid_t pid; int main(int argc,char *argv[]) { int s,len,i; struct sockaddr_in local; char str[100]; void childmain(int); if(argc!=2) { printf("\n usage:%s<no. of childs>",argv[0]); } if((s=socket(AF_INET,SOCK_STREAM,0))==-1) 64

{ perror("socket"); exit(1); } bzero((char *)&local,sizeof(local)); local.sin_family=AF_INET; local.sin_port=htons(atoi(argv[1])); local.sin_addr.s_addr=inet_addr("172.16.0.51"); if(bind(s,(struct sockaddr *)&local,sizeof(local))==-1) { perror("bind"); exit(1); } if(listen(s,5)==-1) { perror("listen"); exit(1); } for(i=0;i<nchilds;i++) if((pid=fork())<0) { perror("fork"); exit(0); } else if(pid==0) childmain(s); return 0; } void childmain(int s) { int done,n,s2,t; struct sockaddr_in remote; char str[100]; for(;;) { t=sizeof(remote); if((s2=accept(s,(struct sockaddr *)&remote,&t))==-1) { perror("accept"); exit(1); } printf("connected.\n"); done=0; do { n=recv(s2,str,100,0); if(n<=0) { if(n<0) perror("recv"); done=1; } if(!done) if(send(s2,str,n,0)<0) { perror("send");

65

printf("my pid is %u",getpid()); done=1; } }while(!done); exit(0); } close(s2); }

/* Program: Preforked client */


#include<stdio.h> #include<stdlib.h> #include<errno.h> #include<string.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> int main(int argc,char *argv[]) { int s,t,len; struct sockaddr_in remote; char str[100]; if(argc!=2) { printf("\n invalid server address"); exit(0); } if((s=socket(AF_INET,SOCK_STREAM,0))==-1) { perror("socket"); exit(1); } printf("trying to connect to %s\n",argv[1]); bzero((char *)&remote,sizeof(remote)); remote.sin_family=AF_INET; remote.sin_port=htons(atoi(argv[2])); remote.sin_addr.s_addr=inet_addr(argv[1]); if(connect(s,(struct sockaddr *)&remote,sizeof(remote))==-1) { perror("connect"); exit(1); } printf("connected.\n"); while(printf(">"),fgets(str,100,stdin),!feof(stdin)) { if(send(s,str,strlen(str),0)==-1) { perror("send"); exit(1); } if((t=recv(s,str,100,0))>0)

66

{ str[t]='\0'; printf("echo>%s",str); } else { if(t<0) perror("recv"); else printf("server closed connection\n"); exit(1); } } close(s); return 0; }

OUTPUT
Server $ gcc preforkserver.c $ ./a.out 6565 connected. Client $ gcc preforkclient.c -o cl $ ./cl 6565 trying to connect to 6565 connected. >hello echo>hello >

67

16. REMOTE FILE ACCESS USIN RPC


Algorithms
Server The server program contains a procedure (remote procedure) that reads the contents of a file that is specified as an argument and returns the contents of that file. Client The client program connects to the server by using UDP and calls the remote procedure on the server using the file name with path. The returned contents of the file are displayed at clients output.

Flow Chart

Server Procedure
Procedure Call with filename as parameter

Client

Open the file specified as parameter

Call the procedure with filename

Read the file Into the buffer

Buffer(Contents of file)

Display the contents of file

Send the buffer to Client

68

//Program

//Interface File (.x file)


program FILE_PROG { version FILE_VERS { string GET_FILE(string) = 1; } =1; } = 0x31234567;

// Server Program
#include <rpc/rpc.h> /* standard RPC include file */ #include<fcntl.h> #include<string.h> #include "file.h" /* this file is generated by rpcgen */ #define MAX 20000 char** get_file_1_svc(char ** argp,struct svc_req *rqstp) { static char *buff; /* must be static */ char *tmp,n; int fd; fd=open(*argp,O_RDONLY); if(fd<0) { perror("file open"); exit(0); } buff=(char *) malloc(MAX); tmp=(char *) malloc(MAX); while(read(fd,tmp,MAX)>0) { strcat(buff,tmp); } close(fd); return(&buff); }

69

// Client Program
#include <stdio.h> #include <rpc/rpc.h> /* standard RPC include file */ #include "file.h" /* this file is generated by rpcgen */ main(int argc, char *argv[]) { CLIENT *cl; /* RPC handle */ char *server,*path; char **sresult; /* return value from get_date_1() */ if (argc != 3) { fprintf(stderr, "usage: %s <hostname> <filename>\n", argv[0]); exit(1); } server = argv[1]; path=argv[2]; /* * Create client handle */ if ((cl = clnt_create(server, FILE_PROG, FILE_VERS, "udp")) == NULL) { /* * can't establish connection with server */ clnt_pcreateerror(server); exit(2); } /* * Now call the remote procedure get_date */ if ( (sresult = get_file_1(&path,cl)) == NULL) { clnt_perror(cl, server); exit(4); } printf("\nFile from host %s is =\n%s\n", server, *sresult); clnt_destroy(cl); /* done with the handle */ exit(0); }

70

OUTPUT
$rpcgen file.x Server $cc fileproc.c o s file_svc.c $./s Client $cc rfile.c o c file_clnt.c $./c 172.16.0.51 file.x File from host 172.16.0.51 is program FILE_PROG { version FILE_VERS { string GET_FILE(string) = 1; } =1; } = 0x31234567;

71

V. Viva Questions
1. What is a Computer Network? 2. What is an Internet? 3. Distinguish between Internet and Intranet. 4. What is a socket? 5. What is the purpose of a socket? 6. What is network programming? 7. What is client-server model? 8. What is a client? 9. What is a server? 10. What are the various types of sockets? 11. What are the different types of server? 12. What is an iterative server? 13. What is a concurrent server? 14. What are the different ways to design a concurrent server? 15. What is byte ordering? 16. List some examples of big-endian systems. 17. List some examples of little-endian systems. 18. What is a signal? 19. How can you block the signal? 20. How can you unblock the signal? 21. List some examples of signals? 22. What are the different I/O models? 23. What is blocking I/O? 24. What is non-blocking I/O? 25. What is asynchronous I/O? 26. Define RPC? 27. What is marshaling? 28. What is un-marshaling? 29. What is XDR? 30. What is IDL? 31. What are the advantages of RPC? 32. What are the different layers in RPC interface? 33. List the different layers of OSI model? 34. Which layer of OSI model implements RPC? 35. List the different layers of TCP/IP model? 36. What is the difference between connection-oriented and connectionless communications? 37. What is the difference between close() and shutdown() system calls? 38. How can you pass multiple arguments to the remote procedure in Sun RPC? 39. What is a port-mapper? 40. What a port? What is the purpose of it? 41. What are the functions of server and client stubs? 42. What is communication domain?

72

43. What are the different types of communication domains? 44. What is the difference between unix and internet domains? 45. What is Bridge. In which TCP/IP layer it is operated. 46. What is Router. In which TCP/IP layer is operated. 47. What is the difference between Repeaters and Amplifiers. In which layer t is operated. 48. What is HDLC? 49. What are the uses of computer networks? 50. How TCP/IP model differs from ISO-OSI model. 51. What are the functions of network layer? 52. What is a virtual circuit? 53. Differentiate between Virtual circuit and Datagram. 54. What is protocol? 55. What is an interface? 56. Differentiate between protocol, service and interface. 57. What is the size of IP address? 58. What are the ranges of Class A,B,C,D & E? 59. What do you mean by subnetting and when it is used 60. What is the maximum size of a datagram as per IP protocol? 61. What is firewall and what are its components. 62. Does IP layer supports reliable service 63. What is congestion? 64. What is the difference between congestion and flow control? 65. How token bucket algorithm differ from leaky bucket algorithm. 66. What is tunneling? 67. List services of transport layer. 68. What are the key elements of transport protocol? 69. What are the QOS parameters of TP layer? 70. How does the transport layer identified processes? 71. Expand DNS, ARPANET, DHCP, SMTP, HTTP, SNMP, MIME, WWW, POP, CGI, RSA, RFC, HDLC, PPP, SDLC, SNA, FTP. 72. Distinguish between TCP and UDP. 73. What is the size of TCP header and IP header? 74. Does a socket support multiple connection. 75. What is proxy server? 76. What is Internet Super server? 77. Does TCP support Multi casting and Broad casting? 78. What is urgent data, Does TCP supports it, What is its size? 79. What kind of connection management may be implemented by TCP? 80. What is well known port? 81. What is reserved port? 82. What do you mean b Asynchronous I/O. What is its use? 83. What is the port number of TELNET, SSH, FTP, HTTP. 84. What is TLI? 85. How network I/O differs from File I/O. 86. What are the primitive file I/O operations in Unix?

73

87. Distinguish between full duplex and half duplex. 88. Distinguish between synchronous and asynchronous transmission. 89. What is an API? 90. What are the fields of an association record? 91. Which routing algorithm may be used by Internet? 92. What is URL? 93. What are the uses of POP3 protocol? 94. What is daemon? 95. What is an email Gateway? 96. Distinguish between SMTP and email. 97. What is the format of DNS resource record? 98. .edu is used for__________and .gov used for _____________ 99. .org is used for__________and .com used for_____________ 100. What are the various protocols available in Application Layer? 101. For what kind of applications UDP is suitable. 102. Differentiate between public key and private key encryption algorithm. 103. What is the need of encryption? 104. What is authentication? 105. Differentiate between authentication and authorization? 106. What is cipher text? 107. What are the advantages and disadvantages of DES? 108. What is the difference between threat and attack? 109. What is the difference between Switch and Hub? 110. What is the difference between Computer networks and Distributed systems?

74

You might also like