Writing Socket Programs

Similar documents
Tutorial on Socket Programming

Introduction to Socket Programming Part I : TCP Clients, Servers; Host information

Unix Network Programming

NS3 Lab 1 TCP/IP Network Programming in C

Socket Programming. Srinidhi Varadarajan

Socket Programming. Kameswari Chebrolu Dept. of Electrical Engineering, IIT Kanpur

Network Programming with Sockets. Anatomy of an Internet Connection

Porting applications & DNS issues. socket interface extensions for IPv6. Eva M. Castro. ecastro@dit.upm.es. dit. Porting applications & DNS issues UPM

Socket Programming. Request. Reply. Figure 1. Client-Server paradigm

Introduction to Socket programming using C

TCP/IP - Socket Programming

Lab 4: Socket Programming: netcat part

CSE 333 SECTION 6. Networking and sockets

IT304 Experiment 2 To understand the concept of IPC, Pipes, Signals, Multi-Threading and Multiprocessing in the context of networking.

ELEN 602: Computer Communications and Networking. Socket Programming Basics

Implementing Network Software

Socket Programming in C/C++

INTRODUCTION UNIX NETWORK PROGRAMMING Vol 1, Third Edition by Richard Stevens

Writing a C-based Client/Server

UNIX. Sockets. mgr inż. Marcin Borkowski

BSD Sockets Interface Programmer s Guide

Computer Networks Network architecture

Programmation Systèmes Cours 9 UNIX Domain Sockets

Network Programming with Sockets. Process Management in UNIX

Hostnames. HOSTS.TXT was a bottleneck. Once there was HOSTS.TXT. CSCE515 Computer Network Programming. Hierarchical Organization of DNS

Application Architecture

Lecture 17. Process Management. Process Management. Process Management. Inter-Process Communication. Inter-Process Communication

Elementary Name and Address Conversions

Elementary Name and Address. Conversions

The POSIX Socket API

VMCI Sockets Programming Guide VMware ESX/ESXi 4.x VMware Workstation 7.x VMware Server 2.0

Interprocess Communication Message Passing

Session NM059. TCP/IP Programming on VMS. Geoff Bryant Process Software

UNIX Sockets. COS 461 Precept 1

System Calls and Standard I/O

An Introductory 4.4BSD Interprocess Communication Tutorial

System Calls Related to File Manipulation

System calls. Problem: How to access resources other than CPU

Client / Server Programming with TCP/IP Sockets

Sources: On the Web: Slides will be available on:

SMTP-32 Library. Simple Mail Transfer Protocol Dynamic Link Library for Microsoft Windows. Version 5.2

DESIGN AND IMPLEMENT AND ONLINE EXERCISE FOR TEACHING AND DEVELOPMENT OF A SERVER USING SOCKET PROGRAMMING IN C

Networks. Inter-process Communication. Pipes. Inter-process Communication

Implementing and testing tftp

A Client-Server Transaction. Systemprogrammering 2006 Föreläsning 8 Network Programming. Hardware Org of a Network Host.

Networks class CS144 Introduction to Computer Networking Goal: Teach the concepts underlying networks Prerequisites:

Packet Sniffing and Spoofing Lab

1 Operating Systems Prof. Dr. Marc H. Scholl DBIS U KN Summer Term IPC may often be used for both

Application Development with TCP/IP. Brian S. Mitchell Drexel University

Review of Previous Lecture

Communication Networks. Introduction & Socket Programming Yuval Rochman

IBM i Version 7.2. Programming Socket programming IBM

OS: IPC I. Cooperating Processes. CIT 595 Spring Message Passing vs. Shared Memory. Message Passing: Unix Pipes

This tutorial has been designed for everyone interested in learning the data exchange features of Unix Sockets.

Network Programming. Chapter The Client-Server Programming Model

Overview. Socket Programming. Using Ports to Identify Services. UNIX Socket API. Knowing What Port Number To Use. Socket: End Point of Communication

transmission media and network topologies client/server architecture layers, protocols, and sockets

ICT SEcurity BASICS. Course: Software Defined Radio. Angelo Liguori. SP4TE lab.

IPC. Semaphores were chosen for synchronisation (out of several options).

Best practices in IPv6 enabled networking software development.

How To Write On A Non-Blocking File On A Thumbtongue (Windows) (Windows 2) (Macintosh) (Amd64) (Apple) (Powerpoint) (Networking) (Unix) (Program) (

CSI 402 Lecture 13 (Unix Process Related System Calls) 13 1 / 17

Shared Memory Segments and POSIX Semaphores 1

Programming guidelines on transition to IPv6

Informatica e Sistemi in Tempo Reale

Concurrent Server Design Alternatives

Generalised Socket Addresses for Unix Squeak

The C Programming Language course syllabus associate level

Software changes for Website and Application IPv6 Readiness

CHAPTER 7. ing with CGI

Outline. Review. Inter process communication Signals Fork Pipes FIFO. Spotlights

Unix System Calls. Dept. CSIE

Linux Driver Devices. Why, When, Which, How?

Department of Electrical Engineering and Computer Science MASSACHUSETTS INSTITUTE OF TECHNOLOGY Operating System Engineering: Fall 2005

CS 213, Fall 2000 Lab Assignment L5: Logging Web Proxy Assigned: Nov. 28, Due: Mon. Dec. 11, 11:59PM

Java Programming: Sockets in Java

Windows Socket Programming & IPv6 Translation Middleware

A Client Server Transaction. Introduction to Computer Systems /18 243, fall th Lecture, Nov. 3 rd

Domain Name System (1)! gethostbyname (2)! gethostbyaddr (2)!

Illustration 1: Diagram of program function and data flow

Client-server Sockets

1 Abstract Data Types Information Hiding

TCP/IP Sockets in C. Practical Guide for Programmers

TFTP Usage and Design. Diskless Workstation Booting 1. TFTP Usage and Design (cont.) CSCE 515: Computer Network Programming TFTP + Errors

1) The postfix expression for the infix expression A+B*(C+D)/F+D*E is ABCD+*F/DE*++

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

KATRAGADDA INNOVATIVE TRUST FOR EDUCATION NETWORK PROGRAMMING. Notes prepared by D. Teja Santosh, Assistant Professor, KPES, Shabad, R.R. District.

Goal: learn how to build client/server application that communicate using sockets. An interface between application and network

REAL TIME OPERATING SYSTEM PROGRAMMING-II: II: Windows CE, OSEK and Real time Linux. Lesson-12: Real Time Linux

Embedded Programming in C/C++: Lesson-1: Programming Elements and Programming in C

Project 1: Implement a simple hosts framework using UNIX TCP Sockets to demonstrate the concept of Mobile Agents

How To Port A Program To Dynamic C (C) (C-Based) (Program) (For A Non Portable Program) (Un Portable) (Permanent) (Non Portable) C-Based (Programs) (Powerpoint)

Operating Systems Design 16. Networking: Sockets

Java Interview Questions and Answers

Division of Informatics, University of Edinburgh

Applications and Services. DNS (Domain Name System)

Glossary of Object Oriented Terms

Introduction. dnotify

RIOT-Lab. How to use RIOT in the IoT-Lab. Oliver "Oleg" Hahm. November 7, 2014 INRIA. O. Hahm (INRIA) RIOT-Lab November 7, / 29

Building a Multi-Threaded Web Server

Transcription:

Writing Socket Programs Laboratorio di Sistemi Operativi Corso di Laurea in Informatica Università degli Studi dell'aquila A.A. 2011/2012 Romina Eramo 1

Writing Socket Programs Any program that uses sockets must include the header files /usr/include/sys/types.h and /usr/include/sys/socket.h. Additional header files must be included based on the socket domain that you wish to use. The most commonly used domains are: Domain AF_UNIX AF_INET Addi*onal header files /usr/include/sys/un.h /usr/include/ne*net/in.h /usr/include/arpa/inet.h /usr/include/netdb.h 2

Different Kinds of Sockets Description of the socket-oriented system calls around a small clientserver example that uses AF_UNIX sockets. The AF_UNIX examples is made up of two programs: 1) chef, the server, which creates a named socket called recipe and writes the recipe to any clients who request it. The recipe is a collection of NULL-terminated strings of variable length. 2) cook, the client, which connects to the named socket called recipe and reads the recipe from the server. It displays the recipe to standard output as it reads it and then terminates. 3

Different Kinds of Sockets The chef server process runs in the background. Any client cook processes that connect to the server cause the server to fork a duplicate server to handle the recipe transfer, allowing the original server to accept other incoming connections. Here s some sample output from the chef and cook example: $ chef & ---> run the server in the background. [1] 5684 $ cook ---> run a client to display the recipe. spam, spam, spam, spam, spam, and spam. $ kill %1 ---> kill the server. [1] Terminated chef $ _ 4

Chef and Cook Listing Chef Server #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> /* For AFUNIX sockets */ #define DEFAULT_PROTOCOL 0 /**************************************************/ main() { int serverfd, clientfd, serverlen, clientlen; struct sockaddr_un serverunixaddress; /* Server address */ struct sockaddr_un clientunixaddress; /* Client address */ struct sockaddr* serversockaddrptr; /* Ptr to server address */ struct sockaddr* clientsockaddrptr; /* Ptr to client address */ 5

/* Ignore death-of-child signals to prevent zombies */ signal(sigchld, SIG_IGN); serversockaddrptr = (struct sockaddr*) &serverunixaddress; serverlen = sizeof( serverunixaddress ); clientsockaddrptr = (struct sockaddr*) &clientunixaddress; clientlen = sizeof( clientunixaddress ); /* Create a UNIX socket, bidirectional, default protocol */ serverfd = socket( AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL ); serverunixaddress.sun_family = AF_UNIX; /*Set domain type */ strcpy( serverunixaddress.sun_path, recipe ); /* Set name */ unlink( recipe ); /* Remove file if it already exists */ bind(serverfd, serversockaddrptr, serverlen); /* Create file */ listen( serverfd, 5 ); /* Maximum pending connection length */ 6

while(1) /* Loop forever */ { /* Accept a client connection */ clientfd = accept( serverfd, clientsockaddrptr, &clientlen); if ( fork() == 0 ) /* Create child to send receipe */ { writerecipe( clientfd ) /* Send the recipe */ close(clientfd); /* Close the socket */ exit( /* EXIT_SUCCESS */ 0 ); /* Terminate */ } else close(clientfd); /* Close the client descriptor */ } } 7

/*************************************************/ writerecipe( fd ) int fd; { static char* line1 = spam, spam, spam, spam, ; static char* line2 = spam, and spam. ; write(fd, line1, strlen(line1)+1); /* Write first line */ write(fd, line2, strlen(line2)+1); /* Write second line */ } 8

Chef and Cook Listing Cook Client #include <stdio.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> /* For AFUNIX sockets */ #define DEFAULT_PROTOCOL 0 /*************************************************/ main() { int clientfd, serverlen, result; struct sockaddr_un serverunixaddress; struct sockaddr* serversockaddrptr; serversockaddrptr = ( struct sockaddr*) &serverunixaddress; serverlen = sizeof( serverunixaddress ); 9

serverlen = sizeof( serverunixaddress ); /* Create a UNIX socket, bidirectional, default protocol */ clientfd = socket( AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL); serverunixaddress.sun_family = AF_UNIX; /* Server domain */ strcpy( serverunixaddress.sun_path, recipe ); /* Server name */ do /* Loop until a connection is made with the server */ { result = connect( clientfd, serversockaddrptr, serverlen); if ( result == -1 ) sleep(1); /* Wait and then try again */ } while ( result == -1 ); readrecipe( clientfd ); /* Read the recipe */ close( clientfd ); /* Close the socket */ exit( /* EXIT_SUCCESS */ 0 ); /* Done */ } 10

/************************************************/ readrecipe( fd ) int fd; { char str[200]; while ( readline(fd, str) ) /* Read lines until end of input */ printf( %s\n, str); /* Echo line from socket */ } /************************************************/ readline(fd, str) int fd; char* str; /* Read a single NULL-terminated line */ { int n; do /* Read characters until NULL or end of input */ { n = read( fd, str, 1 ); /* Read one character */ } while ( n > 0 && *str++!= NULL ); return( n>0 ); /* Return false if end of input */ } 11

Analyzing the Source Code An overview of a server - creating a server socket - naming a server socket - specifying the maximum number of pending connections to a sever socket - accepting connections on a server socket - serving a client An overview of a client - creating a client socket - connecting a client socket to the server socket - communicating via sockets 12

The Server A server is the process that s responsible for creating a names socket and accepting connections to it. To accomplish this task, it must use the following system calls in the order in which they presented : Name socket bind listen accept Meaning creates an unnamed socket gives the socket a name specifies the maximum number of pending connections accepts a socket connection from a client 13

Creating a Socket: socket() A process may create a socket by using socket(), which works like this: System Call : int socket( int domain, int type, int protocol ) socket() creates an unnamed socket of the specified domain, type, and protocol. The legal values of these parameters were described earlier in this section. If socket() is successful, it returns a file descriptor associated with the newly created socket; otherwise, it returns a value of -1. The chef server creates its unnamed socket (line 30): serverfd=socket(af_unix, SOCK_STREAM,DEFAULT_PROTOCOL); 14

Naming a Socket : bind() Once the server has created an unnamed socket, it must be bind it to a name by using bind(), which works like this: System Call : int bind( int fd, const struct sockaddr* address, size_t addresslen ) bind() associates the unnamed socket represented by file descriptor fd with the socket address stored in address. addresslen must contain the length of the address structure. The type and value of the incoming address depend on the socket domain. 15

Naming a Socket : bind() If the socket is in the AF_UNIX domain, a pointer to a sock-addr_un structure must be cast to a sockaddr* and passed in as address. This structure has two fields that should be set as follows: FIELD sun_family sun_path ASSIGN THE VALUE AF_UNIX the full UNIX pathname of the socket( absolute or relative ) If the named AF_UNIX socket already exists, an error occurs, so it s a good idea to unlink() a name before attempting to bind to it. 16

Naming a Socket : bind() If the socket is in the AF_INET domain, a pointer to a socket-addr_in structure must be cast to a sockaddr and passed in as address. This structure has four fields that should be set as follows: FIELD sin_family sin_port sin_addr sin_zero ASSIGN THE VALUE AF_INET the port number of the Internet socket a structure of type in_addr that holds the Internet address leave empty If bind() succeeds, it returns a value of 0; otherwise, it returns a value of -1. 17

Naming a Socket : bind() The chef server assigns the sockaddr_un fields and performs a bind() on lines 31 to 34: serverunixaddress.sun_family = AF_UNIX; /* Set domain type */ strcpy( serverunixaddress.sun_path, recipe ); /* Set name */ unlink( recipe ); /* Remove file if it already exists */ bind( serverfd, serversockaddrptr, serverlen ) /* Create file */ 18

Creating a Socket Queue: listen() When a sever process is servicing a client connection, it s always possible that another client will also attempt a connection. The listen() system call allows a process to specify the number of pending connections that may be queued, and it works like this: System Call: int listen( int fd, int queuelength ) listen() allows you to specify the maximum number of pending connections on a socket. If a client attempts a connection to a socket whose queue is full, it is denied. 19

Creating a Socket Queue: listen() The chef server listens to its named socket, where it specifies a maximum queue length of five: listen( serverfd, 5 ); /* Maximum pending connection length */ 20

Accepting a Client : accept() Once a socket has been created, named, and its queue size has been specified, the final step is to accept connection requests from clients. To do so, the server must use accept(), which works as follows: System Call : int accept( int fd, struct sockaddr* address, int * addresslen ) accept() listens to the named server socket referenced by fd and waits until a connection request from a client is received. When this event occurs, accept() creates an unnamed socket with the same attributes as those of the original named server socket, connects it to the client s socket. and returns a new file descriptor that may be used for communication with the client. 21

Accepting a Client : accept() The original named server socket may be used to accept more connections. The address structure is filled with the address of the client and is normally only used in conjuction with Internet connections. The addresslen field should be initially set to point to an integer containing the size of the structure pointed to by address. When a connection is made, the integer that it points to is set to the actual size, in bytes, of the resulting address. If accept() succeeds, it returns a new file descriptor that may be used to talk with the client; otherwise, it returns a value of -1. 22

Accepting a Client : accept() The chef sever accepts a connection clientfd = accept( serverfd, clientsockaddrptr, &clientlen ); Serving a client when a client connection succeeds, the most common sequence of events is as follows: The server process forks. The parent process closes the newly formed client file descriptor and loops back to accept(), ready to service new connection requests from clients. The child process talks to the client using read() and write(). When the conversation is complete, the child process closes the client file descriptor and exits. 23

Accepting a Client : accept() The chef sever process while( 1 ) /* Loop forever */ { /* Accept a client connection */ clientfd = accept( serverfd, clientsockaddrptr, &clientlen ); } if ( fork()==0 ) /* Create child to send receipe */ { writerecipe( clientfd ); /* Send the recipe */ close(clientfd); /* Close the socket */ exit( /* EXIT_SUCCESS */ 0 ); /* Terminate */ } else close(clientfd); /* Close the client descriptor */ 24

The Client A client is a process that s responsible for creating an unnamed socket and then attaching it to a named server socket. To accomplish this task, it muse use the following system calls in order in which they are presented: Name socket connect Meaning creates an unnamed socket attaches an unnamed client socket to a named server socket 25

Creating a Socket: socket() a client uses socket() to create an unnamed socket is the same as the way that the server uses it. The domain, type, and protocol of the client socket must match those of the targeted server socket. The cook client process creates its unnamed socket clientfd = socket( AF_UNIX, SOCK_STREAM, DEFAULT_PROTOCOL); 26

Making the Connection : connect() To connect to a sever s socket, a client process must fill a structure with the address of the server s socket and then use connect, which works like this: System Call: int connect(int fd, struct sockaddr* address,int addresslen) connect() attempts to connect to a sever socket whose address is contained within a structure pointed to by address. If connect() successful, fd may be used to communicate with the server s socket. The type of structure to which address points must follow the same rules as those stated in the description of bind() : 27

Making the Connection : connect() If the socket is in the AF_UNIX domain, a pointer to a sock-addr_un structure must be cast to a( sockaddr* ) and passed in as address. If the socket is in the AF_INET domain, a pointer t a sock-addr_un structure must be cast to a ( sockaddr* ) and passed in as address. addresslen must be equal to the size of the address structure. For examples of Internet clients, see the next examples of a socket and the Internet-shell program at the end of this chapter. If the connection is made, connect() returns a value of 0. If the server socket doesn t exist or its pending queue is currently filled, connect() returns a value of -1. 28

Making the Connection : connect() The cook client process calls connect() until a successful connection is made. do /* Loop until a connection is made with the server */ { result = connect( clientfd, serversockaddrptr, serverlen ); if ( result == -1 ) sleep(1); /* Wait and then try again */ } while ( result == -1 ); 29

Communicating Via Sockets Once the server socket and client socket have connected, their file descriptors may be used by write() and read(). writerecipe(fd) int fd; { static char* line1= spam, spam, spam, spam, ; static char* line2= spam, and spam. ; write(fd, line1, strlen(line1)+1); /* Write first line */ write(fd, line2, strlen(line2)+1); /* Write second line */ } 30

Communicating Via Sockets The client uses read() readline( fd, str ) int fd; char* str; /* Read a single NULL-terminated line */ { int n; do /* Read characters until NULL or end of input */ { n=read(fd, str, 1); /* Read one character */ } while ( n>0 && *str++!= NULL ); } return ( n > 0 ); /* Return false if end of input */ The server and client should be careful to close their socket file descriptors when they are no longer needed. 31

Internet Sockets The AF_UNIX sockets that you ve seen so far are fine for learning about sockets, but they aren t where the action is. An Internet socket is specified by two values: a 32-bit IP address, which specifies a single unique Internet host, and a 16-bit port number, which specifies a particular port on the host. These specifications mean that an Internet client must know not only the IP address of the server, but also the server s port number. Several standard port numbers are reserved for system use. For example, port 13 is always served by a process that echoes the host s time of day to any client that s interested. 32

Internet Sockets The first example, allows the connection to port 13 of any Internet host in the world and find the remote time of day. It allows three kinds of Internet addresses: If you enter s, it automatically means the local host. If you enter something that starts with a digit, it s assumed to be an A.B.C.D-format IP address and is converted into a 32-bit IP address by software. If you enter a string, it s assumed to be a symbolic host name and is converted into a 32-bit IP address by software. 33

Internet Sockets Sample Output $ inettime ---> run the program. Host name ( q=quit, s=self ) : s ---> what s my time? Self host name is csservr2 Internet Address = 129.110.42.1 The time on the target port is Fri Mar 27 17:03:50 1998 Host name ( q=quit, s=self ): wotan ---> what s the time on wotan? Internet Address=129.110.2.1 The time on the target port is Fri Mar 27 17:03:55 1998 Host name ( q=quit, s=self ): 192.112.36.5 ---> what s the time at ---> ddn.nic.mil. The time on the target port is Fri Mar 27 18:02:02 1998 Host name ( q=quit, s=self ): q ---> quit program. $ _ 34

Internet Time Client Listing #include <stdio.h> #include <signal.h> #include <ctype.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> /* For AFINET sockets */ #include <arpa/inet.h> #include <netdb.h> #define DAYTIME_PORT 13 /* Standard port 0 */ #define DEFAULT_PROTOCOL 0 unsigned long promptforinetaddress(); unsigned long nametoaddr(); /**************************************************/ main() { int clientfd; /* Client socket file descriptor */ 35

Internet Time Client Listing (2) int serverlen; /* Length of server address structure */ int result; /* From connect() call */ struct sockaddr_in severinetaddress; /* Server address */ struct sockaddr* serversockaddrptr; /* Pointer to address */ unsigned long inetaddress; /* 32-bit IP address */ /* Set the two server variables */ serversockaddrptr = ( struct sockaddr* ) &serverinetaddress; serverlen = sizeof ( serverinetaddress ); /* Length of address */ while( 1 ) /* Loop until break */ { inetaddress = promptforinetaddress(); /* Get 32-bit IP */ if ( inetaddress == 0 ) break; /* Done */ /* Start by zeroing out the entire address structure */ bzero( (char*)&serverinetaddress, sizeof( serverinetaddress)); 36

Internet Time Client Listing (3) serverinetaddress.sin_family = AF_INET; /* Use Internet */ serverinetaddress.sin_addr.s_addr=inetaddress; /* IP */ serverinetaddress.sin_port = htons(daytime_port); /* Now create the client socket */ clientfd = socket( AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL); do /* Loop until a connection is made with the server */ { result = connect( clientfd, seversockaddrptr, serverlen ); if ( result== -1 ) sleep(1); /* Try again in 1 second */ } while ( result==-1 ); readtime( clientfd ); /* Read the time from the server */ close(clientfd); /* Close the socket */ } exit( /* EXIT_SUCCESS */ 0 ); } 37

Internet Time Client Listing (4) /************************************************/ unsigned long promptforinetaddress() { char hostname[100]; /* Name from user: numeric or symbolic */ unsigned long inetaddress; /* 32-bit IP format */ /* Loop until quit or a legal name is entered */ /* If quit, return 0; else return host s IP address */ do { printf( Host name( q=quit, s=self) : ); scanf( %s, hostname); /* Get name from keyboard */ if ( strcmp(hostname, q ) == 0 ) return (0); /* Quit */ inetaddress = nametoaddr(hostname); /* Convert to IP */ if ( inetaddress == 0 ) printf( Host name not found \n ); } while( inetaddress==0 ); } 38

Internet Time Client Listing (5) /************************************************/ unsigned long nametoaddr(name) char* name; { char hostname[100]; struct hostent* hoststruct; struct in_addr* hostnode; /* Convert name into a 32-bit IP address */ /* If name begins with a digit, assume it s a valid numeric */ /* Internet address of the form A.B.C.D and convert directly */ if ( isdigit(name[0]) ) return ( inet_addr(name) ); if ( strcmp(name, s ) ==0 ) /* Get host name from database */ { gethostname(hostname, 100); printf( Self host name is %s\n, hostname); } 39

Internet Time Client Listing (6) else /* Assume name is a valid symbolic host name */ strcpy( hostname, name); /* Now obtain address information from database */ hoststruct = gethostbyname(hostname); if ( hoststruct == NULL ) return(0); /* Not Found */ /* Extract the IP Address from the hostent structure */ hostnode = ( struct in_addr* ) hoststruct->h_addr; /* Display a readable version for fun */ printf( Internet Address=%s\n, inet_ntoa(*hostnode)); } return ( hostnode->s_addr ); /* Return IP address */ 40

Internet Time Client Listing (7) readtime( fd ) int fd; { char str[200]; /* Line buffer */ printf( The time on the target port is ); while( readline(fd,str) ) /* Read lines until end of input */ printf( %s\n, str); /* Echo line from server to user */ } /***************************************************/ readline( fd, str ) int fd; char* str; /* Read a single line terminated by a new line */ { int n; 41

Internet Time Client Listing (8) do /* Read characters until NULL or end of input */ { n = read(fd, str, 1); /* Read one character */ } while( n>0 && *str++!= \n ) ; } return ( n>0 ); /* Return false if end of input */ 42

Analyzing the Source Code Internet Clients The procedure for creating an Internet client is the same as that for creating an AF_UNIX client, Internet socket address structure is of the type struct sockaddr_in and has four fields: sin_family, the domain of the socket, which should be set to AF_INET sin_port, the port number, which is 13 in this case sin_port, the 32-bit IP number sin_zero, which is padding and is not set 43

Analyzing the Source Code promptforinetaddress() gets the host s name from the user and then invokes nametoaddr() to convert into an IP address. If the user enters a string starting with a digit, inet_addr() is invoked to perform the conversion. Library Call: in_addr_t inet_addr(const char* string) inet_addr() returns the 32-bit IP address that corresponds to the A.B.C.D-format string. The IP address is in network-byte order. 44

Analyzing the Source Code Network-byte order a host-neutral ordering of bytes in the IP address. This ordering is necessary, since regular byte ordering can differ from machine to machine, which would make IP addresses nonportable. If the string doesn t start with a digit, the next step is to see if it s s, which signifies the local host. The name of the local host is obtained by gethostname(), which works as follows: System Call: int gethostname( char* name, int namelen ) gethostname() sets the character array pointed to by name of length namelen to a NULL-terminated string equal to the local host s name. 45

Analyzing the Source Code Once the symbolic name of the host is determined, the next stage is to look it up in the network-host file, /etc/hosts. This task is performed by gethostbyname(), which works like this: Library Call : struct hostent* gethostbyname( const char* name ) gethostbyname() searches the /etc/hosts file and returns a pointer to a hostent structure that describes the file entry associated with the string name. If name is not found in the /etc/hosts file, NULL is returned. 46

Analyzing the Source Code The hostent structure has several fields, but the only one we re interested in is a field of type ( struct in_addr*) called h_addr. This field contains the host s associated IP number in a subfield called s_addr. Before returning this IP number, the program displays a string description of the IP address by calling inetntoa() Library Call: char* inet_ntoa( struct in_addr address ) inet_ntoa() takes a structure of type in_addr as its argument and returns a pointer to a string that describes the address in the format A.B.C.D. 47

Analyzing the Source Code Once the IP address inetaddress has been determined, the client s socket address fields are filled by (lines 37 to 40): bzero((char*)&serverinetaddress, sizeof(serverinetaddress)); serverinetaddress.sin_family = AF_INET; /* Use Internet */ serverinetaddress.sin_addr.s_addr = inetaddress; /* IP */ serverinetaddress.sin_port = htons(daytime_port); bzero() clears the socket address structure s contents before its fields are assigned: Library Call: void bzero(void* buffer, size_t length) bzero() fills the array buffer or size length with zeroes( ASCII NULL). 48

Analyzing the Source Code The bzero() call had its origins in the Berkeley version of UNIX. System V s equivalent is memset() : Library Call: void memset(void* buffer, int value, size_t length) memset() fills the array buffer of size length with the value of value. Like the IP address, the port number is also converted to a networkbyte ordering by htons(), which works like this: 49

Analyzing the Source Code Like the IP address, the port number is also converted to a networkbyte ordering by htons(), which works like this: Library Call: in_addr_t htonl(in_addr_t hostlong) in_port_t htons(in_port_t hostshort) in_addr_t ntohl(in_addr_t networklong) in_port_t ntohs(in_port_t networkshort) Each of these functions performs a conversion between a host-format number and a network-format number. For example, htonl() returns the network-format equivalent of the host-format unsigned long hostlong, and ntohs() returns the host-format equivalent of the networkformat unsigned short networkshort. 50

Analyzing the Source Code The final step is to create the client socket and attempt the connection. The code for this task is almost the same as that for AF_UNIX sockets: clientfd = socket( AF_INET, SOCK_STREAM, DEFAULT_PROTOCOL); do /* Loop until a connection is made with the server */ { result = connect( clientfd, serversockaddrptr, serverlen ); if ( result == -1 ) sleep(1); /* Try again in 1 second */ } while ( result == - 1 ); 51

Internet Servers Constructing an Internet server is actually pretty easy. The sin_family, sin_port, and sin_zero fields of the socket_address structure should be filled in as they were in the client example. The only difference is that the s_addr field should be set to the network-byte-ordered value of the constant INADDR_ANY, which means accept any incoming client requests. The following example of how to create a server socket address is a slightly modified version of some code taken from the Internet shell program that ends this chapter: int serverfd; /* Server socket */ struct sockaddr_in serverinetaddress; /* Server Internet address */ struct sockaddr* serversockaddrptr; /* Pointer to server address */ struct sockaddr_in clientinetaddress; /* Client Internet address */ 52

Internet Servers struct scokaddr* clientsockaddrptr; /* Pointer to client address */ int port=13; /* Set to the port that you wish to serve */ int serverlen; /* Length of address structure */ serverfd = socket(af_inet, SOCK_STREAM, DEFAULT_PROTOCOL); /* Create */ serverlen = sizeof(serverinetaddress); /* Length of structure */ bzero((char*) &serverinetaddress, serverlen); /* Clear structure */ serverinetaddress.sin_family = AF_INET; /* Internet domain */ serverinetaddress.sin_addr.s_addr = htonl(inaddr_any); /* Accept all */ serverinetaddress.sin_port = htons(port); /* Server port number */ 53

Internet Servers When the address is created, the socket is bound to the address, and its queue size is specified in the usual way: serversockaddrptr = (struct sockaddr*) &serverinetaddress; bind( serverfd, serversockaddrptr, serverlen); listen(serverfd, 5); The final step is to accept client connections. When a successful connection is made, the client socket address is filled with the client s IP address and a new file descriptor is returned: clientlen = sizeof( clientinetaddress ); clientsockaddrptr = ( struct sockaddr* ) clientinetaddress; clientfd = accept(serverfd, clientsockaddrptr, &clientlen); an Internet server s code is very similar to that of an AF_UNIX server. 54

Shared Memory Sharing a segment of memory is a straightforward and intuitive method of allowing two processes on the same machine to share data. Accessing a shared memory segment is the fasted form of IPC, since no data has to copied or sent anywhere else. some of the common system calls used to allocate and use shared memory segments in System V-based versions of UNIX are: shmget(), which allocates a shared memory segment and returns the segment ID number shmat(), which attaches a shared memory segment to the virtual address space of the calling process shmdt(), which detaches an attached segment from the address space shmctl(), which allows you to modify attributes associated with the shared memory segment( e.g., access permissions ) 55