Sockets. 1 Introduction. (Reference:, Gray Chapter 10) Network Programming Lecture Notes by. Turhan TUNALI

Similar documents
Dept. of Computer Science & Engineering 1 Knowledge & Data Engineering Lab.

Application Programming Interfaces

Hyo-bong Son Computer Systems Laboratory Sungkyunkwan University

Socket Programming. CSIS0234A Computer and Communication Networks. Socket Programming in C

Lab 0. Yvan Petillot. Networks - Lab 0 1

The BSD UNIX Socket Interface (CS 640 Lecture) Assignment 1. Interprocess Communication (IPC) Work Individually (no groups)

Introduction to Socket Programming

Lecture 7. Followup. Review. Communication Interface. Socket Communication. Client-Server Model. Socket Programming January 28, 2005

Department of Computer Science

Sockets. Dong-kun Shin Embedded Software Laboratory Sungkyunkwan University Embedded Software Lab.

CS118 Discussion 1B, Week 1. Taqi Raza BUNCHE 1209B, Fridays 12:00pm to 1:50pm

How do we Communicate? Introduction to Unix Network Programming. What does Alice do? What does Bob do? Two simplest networking programs


Sockets. Jin-Soo Kim Computer Systems Laboratory Sungkyunkwan University

Unix Network Programming

System Programming. Sockets

CS 640: Computer Networking

CS 3516: Computer Networks

PA #2 Reviews. set_name, get_name, del_name. Questions? Will be modified after PA #4 ~

Programming with TCP/IP. Ram Dantu

ECE 435 Network Engineering Lecture 2

Tutorial on Socket Programming

Processes communicating. Network Communication. Sockets. Addressing processes 4/15/2013

Network Socket Programming - 3 BUPT/QMUL

Network Socket Programming - 3 BUPT/QMUL

SOCKETS. COMP750 Distributed Systems

ECE 435 Network Engineering Lecture 2

TCP/IP Sockets in C: Practical Guide for Programmers. Computer Chat. Internet Protocol (IP) IP Address. Transport Protocols. Ports

An Introductory 4.4BSD Interprocess Communication Tutorial

Types (Protocols) Associated functions Styles We will look at using sockets in C Java sockets are conceptually quite similar

Linux Network Programming, Part 1

Internet protocol stack. Internetworking II: Network programming. April 20, UDP vs TCP. Berkeley Sockets Interface.

CS4514 B08 HELP Session 1

ICT 6544 Distributed Systems Lecture 5

Internetworking II: Network programming. April 20, 2000

WinSock. What Is Sockets What Is Windows Sockets What Are Its Benefits Architecture of Windows Sockets Network Application Mechanics

Network Programming November 3, 2008

Chapter 6. The Transport Layer. Transport Layer 3-1

CSC209H Lecture 9. Dan Zingaro. March 11, 2015

Client-server model The course that gives CMU its Zip! Network programming Nov 27, Using ports to identify services.

CS321: Computer Networks Socket Programming

CS307 Operating Systems Processes

Processes. Process Concept. The Process. The Process (Cont.) Process Control Block (PCB) Process State

Oral. Total. Dated Sign (2) (5) (3) (2)

Lecture 24. Thursday, November 19 CS 375 UNIX System Programming - Lecture 24 1

Network Programming Worksheet 2. Simple TCP Clients and Servers on *nix with C.

Session NM056. Programming TCP/IP with Sockets. Geoff Bryant Process software

CS4700/CS5700 Fundamentals of Computer Networking

Sockets. UNIX-style IPC. Silberschatz, Galvin and Gagne 2005 Msc. Ivan A. Escobar Broitman 2007

CS321: Computer Networks Introduction to Application Layer

Network Communication

Socket Programming TCP UDP

Christian Tschudin (basierend auf einem Foliensatz von C. Jelger und T. Meyer) Departement Mathematik und Informatik, Universität Basel

SOCKET PROGRAMMING. What is a socket? Using sockets Types (Protocols) Associated functions Styles

Communication. Communication. Distributed Systems. Networks and protocols Sockets Remote Invocation Messages Streams. Fall /10/2001 DoCS

NETWORK PROGRAMMING. Instructor: Junaid Tariq, Lecturer, Department of Computer Science

Socket Programming. Dr. -Ing. Abdalkarim Awad. Informatik 7 Rechnernetze und Kommunikationssysteme

CS4514 (C04) HELP Session 1 Introduction to Network Programming (v1.3)

Distributed programming

Interprocess Communication

Sockets Sockets Communication domains

TCP Network Programming in C

Ports under 1024 are often considered special, and usually require special OS privileges to use.

Socket Programming 2007/03/28

Network Socket Programming - 2 BUPT/QMUL

518 Lecture Notes Week 12

Interprocess Communication Mechanisms

Interprocess Communication Mechanisms

Socket Programming for TCP and UDP

A. Basic Function Calls for Network Communications

Chapter 2 Applications and

MSc Integrated Electronics Networks Assignment. Investigation of TCP/IP Sockets and Ports. Gavin Cameron

CompSci 356: Computer Network Architectures Lecture 3: Hardware and physical links References: Chap 1.4, 1.5 of [PD] Xiaowei Yang

// socket for establishing connections

Hybrid of client-server and P2P. Pure P2P Architecture. App-layer Protocols. Communicating Processes. Transport Service Requirements

A Client-Server Exchange

Piotr Mielecki Ph. D.

sottotitolo Socket Programming Milano, XX mese 20XX A.A. 2016/17 Federico Reghenzani

Overview. Administrative. * HW# 5 Due next week. * HW# 5 : Any Questions. Topics. * Client Server Communication. * 12.

#1 socket_server.c socket_client.c

Context. Distributed Systems: Sockets Programming. Alberto Bosio, Associate Professor UM Microelectronic Departement

TCP/IP Sockets in C: Practical Guide for Programmers. Computer Chat. Internet Protocol (IP) IP Address. Transport Protocols

CLIENT-SIDE PROGRAMMING

Socket Programming. What is a socket? Using sockets. Types (Protocols) Associated functions Styles

Internetworking with Sockets 1/67

Sockets. Dong-kun Shin Embedded Software Laboratory Sungkyunkwan University Embedded Software Lab.

Elementary TCP Sockets

Network programming(i) Lenuta Alboaie

ECE322 Systems Programming Project 2: Networking with Matrix Multiplication in C Grant Kimes 12/16/15

The User Datagram Protocol

Introduction to Network Programming using C/C++

1 /* client.c - adapted from code for example client program that uses TCP */ 2 /*Modified by Vincent Chu, Winter

Project 3. Reliable Data Transfer over UDP. NTU CSIE Computer Networks 2011 Spring

The Berkeley Sockets API. Networked Systems Architecture 3 Lecture 4

Client/Server. Networking Approach.

EEC-484/584 Computer Networks

CSE 333 SECTION 8. Sockets, Network Programming

Network Programming in C: The Berkeley Sockets API. Networked Systems 3 Laboratory Sessions

UDP CONNECT TO A SERVER

Transcription:

Sockets (Reference:, Gray Chapter 10) Network Programming Lecture Notes by 1 Introduction Turhan TUNALI Unix uses a common interface for the access of files and devices that reside on a single host. The common sequence is open read write close. Although a similar approach is taken for the system V IPC tools, the application for each tool introduced specific commands. The use of RPC is also complex and restrictive. What is needed is an extension of the read-write paradigm with the inclusion of sufficient networking semantics to permit unrelated processes, on different hosts, to communicate as if they were reading and writing to a local file. Two different Application Program Interfaces (API) are developed o Berkeley Socket Interface o Transport Level Interface (TLI) We will deal with Berkeley Sockets in this lecture.

A socket is an abstract data structure that is used to create a channel (connection point) to send and receive information between unrelated processes. A usual sequence of events can be as follows: o Server: Create socket Map the socket to a local address Wait for requests from clients o Client: Create socket Determine information (host name, port number) about server Send and receive information. 2 Communication Basics 2.1 Network Addresses Every host on a network has two unique addresses: o Ethernet address: Assigned by the manufacturer 48 bits Written in Hexadecimal notation Six eight bit numbers Example: Ethernet address of Abel is 8:0:20:85:69:5a

o Internet address Assigned by Internet authorities 32 bits Four eight bit numbers Written in decimal separated by dots Example: Internet address (IP) of Abel is 147.126.2.4 The system maps Internet address to Ethernet address. This is done by using Address Resolution Protocol (ARP). 2.2 Domains-Network and Communication

More convenient method is used to represent IP addresses. Ex: cs.luc.edu. Domain Name Server (DNS) provides the mapping between the latter and the IP addresses. In this lecture, we will use the term domain to indicate communication type for socket interface. There are two types of socket communication domains: o UNIX Domain: Sockets have actual file names Sockets can only be used with processes that reside in the same host o Internet Domain: Sockets allow unrelated processes on different hosts to communicate 2.3 Protocol Families We will mostly be dealing with UDP and TCP in this lecture. 2.4 Socket Types Data can be sent in two different ways: o Stream of bits o Datagrams containing address, error control and other information Accordingly, we specify two basic socket types: o Stream Sockets Reliable

Allow full-duplex communication Connection oriented o Datagram Sockets Unreliable Allow full-duplex communication Connectionless 3 IPC Using SOCKETPAIR The socketpair network call is used to create pair of sockets for UNIX domain: int socketpair ( int family, int type, int protocol, int sv[2] ); The first argument is set to PF_UNIX. o Later on we will use PF_INET for Internet. The second argument can be o SOCK_STREAM o SOCK_DGRAM The third argument is set to 0 to indicate default. o Default for Internet is UDP for connectionless sockets TCP for connection-oriented sockets The fourth argument is the base address of an integer array that will reference the two socket descriptors that will be created

Each descriptor is bi-directional and is available both for reading and writing. The following program creates a socket pair, forks a child, and uses sockets to communicate the parent and the child: Note that the socket library must be passed to the compiler via -lsocket. /* * Program 10.1 Creating a socket pair #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #define BUF_SZ 10 main(void) { int sock[2], /* The socket pair cpid, i; static char buf[buf_sz]; /* Temporary buffer for message if (socketpair(pf_unix, SOCK_STREAM, 0, sock) < 0) { perror("generation error"); exit(1); switch (cpid = (int) fork()) { case -1: perror("bad fork"); exit(2); case 0: /* The child process close(sock[1]); for (i = 0; i < 10; i += 2) { sleep(1); sprintf(buf, "c: %d\n", i); write(sock[0], buf, sizeof(buf)); read(sock[0], buf, BUF_SZ); printf("c-> %s", buf); /* Message from parent close(sock[0]); break; default: /* The parent process close(sock[0]); for (i = 1; i < 10; i += 2) { sleep(1); read(sock[1], buf, BUF_SZ); printf("p-> %s", buf); /* Message from child sprintf(buf, "p: %d\n", i); write(sock[1], buf, sizeof(buf));

close(sock[1]); return 0; Before the process forks, both sock[0] and sock[1] descriptors are available in parent for reading and writing. After the fork, the child process closes sock[1] and reads and writes with sock[0]. The parent process closes sock[0] and reads and writes with sock[1]. At the kernel level the sockets are still one and the same. Thus, what the child process writes to sock[0] can be read by the parent process from sock[1].

4 Sockets The Connection-Oriented Paradigm Used in a client-server communication model. Server connection-oriented communication sequence o Create a socket, socket( ) o Assign a name to a socket, bind( ) o Establish a queue for connections, listen( ) o Extract a connection from the queue, accept( ) o Reply to the request Client connection-oriented communication sequence o Create a socket, socket( ) o Initiate a connection, connect( ) o Send request to the server

The socket network call is as follows: ); int socket( int family, int type, int protocol The first argument can be o PF_UNIX o PF_INET The second argument can be

o SOCK_STREAM o SOCK_DGRAM The third argument is set to 0 for default. If the process creating the socket is to act as a server, then the socket must be bound. The bind network call is used for this purpose: int bind( int socket, const struct sockaddr *name, int namelen); The first argument is the integer returned from the socket call. The second argument is a reference to struct sockaddr { u_short sa_family; char sa_data[14]; ; If the socket is for UNIX domain, we have the following: o For UNIX Domain sockets, a reference to a file must be bound to the socket. A UNIX socket domain address is defined as struct sockaddr_un { short sun_family; char sun_path[108]; ;

o In above The first member is AF_UNIX The second member is the path to the file name bind will create the file entry for the socket If the socket is for Internet domain, we have the following: o An Internet domain address field is defined as struct sockaddr_in { short sin_family; u_short struct sin_addr; char sin_zero[8]; sin_port; in_addr The first member is AF_INET The second member is 16 bit port number In the third member, sin_addr is reference to in_addr that holds the 32 bit internet address. The fourth member is currently unused We can now complete the definition of the second argument of the bind call:

The first member of sockaddr indicates the address family The second member is a reference to the actual address where either sockaddr_in or sockaddr_un is passed Finally, the third argument of bind is the size of the address structure Next network call issued is listen: int listen( int backlog ); int socket, The first argument is the socket descriptor The second argument denotes the maximum size of the queue Next is the accept call. This call will block if there are no pending connection requests int accept( *addr, int socket, struct sockaddr int *addrlen );

The first argument is a socket descriptor that has previously been bound to an address with bind network call and is currently listening for connection The second argument is a pointer to sockaddr. The third argument is the length of sockaddr. If successful, accept returns a new socket descripter and the old one continues accepting other client calls In a connection oriented setting, the client process initiates the connection with the server process with the connect network call. int connect( int socket, struct sockaddr *name, int namelength ); The first argument is the socket descriptor The second argument: o If connection-oriented, *name references the address of the socket with which it wants to communicate o If connectionless, *name will reference where (address) the datagrams are to be sent. o If protocol is UNIX, name references a path/file name AF_INET, name references an Internet address/port number pair

Once the connection between the client and server has been established, they can communicate using standard I/O calls such as read and write or one of special calls such as send and receive. When they are done, they issue a close. 4.1 A UNIX Domain Stream Socket Example The server creates a socket, binds it to an address, generates a wait queue, accepts a connection, reads from socket displays it on screen. Client creates a socket, connect to the server, generates ten messages and sends them to the server. The Unix addresses of client and server are known in advance. /* Server - UNIX domain, connection-oriented #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> /* as we are using UNIX protocol #define NAME "my_sock" main( void ) { int orig_sock, /* Original socket descriptor in server new_sock, /* New socket descriptor from connect clnt_len, /* Length of client address i; /* Loop counter static struct sockaddr_un clnt_adr, /* UNIX addresses of client and server serv_adr; static char buf[10]; /* Buffer for messages void clean_up( int, char *); /* Close socket and remove it routine

if ((orig_sock = socket(af_unix, SOCK_STREAM, 0)) < 0) {/* SOCKET perror("generate error"); exit(1); serv_adr.sun_family = AF_UNIX; /* Set tag appropriately strcpy(serv_adr.sun_path,name);/* Assign name (108 chars max) unlink(name); /* Remove old copy if present if (bind( orig_sock, (struct sockaddr *) &serv_adr, /* BIND sizeof(serv_adr.sun_family)+strlen(serv_adr.sun_path)) < 0) { perror("bind error"); clean_up(orig_sock, NAME); exit(2); listen(orig_sock, 1); /* LISTEN clnt_len = sizeof(clnt_adr); if ((new_sock = accept( orig_sock, (struct sockaddr *) &clnt_adr, &clnt_len)) < 0) { /* ACCEPT perror("accept error"); clean_up(orig_sock, NAME); exit(3); for (i = 1; i <= 10; i++) { /* Process sleep(1); read(new_sock, buf, sizeof(buf)); printf("s-> %s", buf); close(new_sock); clean_up(orig_sock, NAME); exit(0); void clean_up( int sd, char *the_file ){ close( sd ); unlink( the_file ); /* close it /* rm it /* Client - UNIX domain, connection-oriented #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h>

#include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #define NAME "my_sock" main( void ) { int orig_sock, /* Original socket descriptor in client i; /* Loop counter static struct sockaddr_un serv_adr; /* UNIX address of the server process static char buf[10]; /* Buffer for messages if ((orig_sock = socket(af_unix, SOCK_STREAM, 0)) < 0) { /* SOCKET perror("generate error"); exit(1); serv_adr.sun_family = AF_UNIX; /* Set tag appropriately strcpy(serv_adr.sun_path, NAME);/* Assign name if (connect( orig_sock, (struct sockaddr *) &serv_adr, /* CONNECT sizeof(serv_adr.sun_family)+strlen(serv_adr.sun_path)) < 0) { perror("connect error"); exit(1); for (i = 1; i <= 10; i++) { /* Send msgs sprintf(buf, "c: %d\n", i); write(orig_sock, buf, sizeof(buf)); close(orig_sock); exit(0);

4.2 An Internet Domain Stream Socket Example We need host information to set up communications in this case. The gethostbyname network call returns information about a host if we know its name. ); struct hostent *gethostbyname( const char *name The only parameter takes a single character string reference that contains the name of the host. The call will return a reference to a hostent structure: struct hostent { char *h_name; char **h_aliases;

int h_addrtype; int h_length; char **h_addr_list; #define h_addr h_addr_list[0] ; The following program uses gethostbyname to obtain information about a host. Note that lnsl must be added to the compilation line. /* Checking host entries #include <stdio.h> #include <sys/types.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> main( void ) { struct hostent *host; static char who[10]; printf("enter host name to look up: "); scanf("%10s", who); host = gethostbyname( who ); if ( host!= (struct hostent *) NULL ) { printf("here is what I found about %s :\n", who); printf("official name : %s\n", host->h_name); printf("aliases : "); while ( *host->h_aliases ) { printf("%s ", *host->h_aliases ); ++host->h_aliases; printf("\naddress type : %i\n", host->h_addrtype); printf("address length: %i\n", host->h_length); printf("address list : "); while ( *host->h_addr_list ) { struct in_addr in; memcpy( &in.s_addr, *host->h_addr_list, sizeof (in.s_addr)); printf("[%s] = %s ", *host->h_addr_list, inet_ntoa(in)); ++host->h_addr_list; printf("\n");

Note that the inet_ntoa network call translates the character encoded network address into standard dotted notation. In addition to the Internet address, the client must also know the port number of the particular service on a server. An application can issue getservbyname network call to obtain such information. struct servent *getservbyname( const char *name, char *proto ); The getservbyname is passed the name of the service and protocol. It returns a reference to a servent structure. struct servent { char *s_name; char **s_aliases; int s_port; char *s_proto; ; The following program uses getservbyname network call to return information about a selected service type for a given protocol. /* Checking service -- port entries for a host #include <stdio.h> #include <netdb.h> #include <netinet/in.h> main( void ) { struct servent *serv; static char protocol[10], service[10];

printf("enter service to look up : "); scanf("%9s", service); printf("enter protocol to look up: "); scanf("%9s", protocol); serv = getservbyname( service, protocol ); if ( serv!= (struct servent *)NULL ) { printf("here is what I found \n"); printf("official name : %s\n", serv->s_name); printf("aliases : "); while ( *serv->s_aliases ) { printf("%s ", *serv->s_aliases ); ++serv->s_aliases; printf("\nport number : %i\n", htons(serv->s_port)); printf("protocol Family: %s\n\n", serv->s_proto); else printf("service %s for protocol %s not found\n",service,protocol); Note that the port number is passed through a network function ntohs that maintains byte ordering during the conversion of 16 and 32 bit integer values: u_short ntohs(u_short netshort); The inverse of ntohs is htons. The letter s indicates that argument is short 16 bits. For long integers, similar calls are ntohl and htonl.

The following program uses Internet protocol with connection oriented sockets. The server receives messages from clients, change the case of the message and return it to the client. Communication terminates when client sends a. in column one. For each connection, server forks a child that will carry on the communication. #include <stdio.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/ioctl.h> #include <sys/sockio.h> #define PORT 6969 static char buf[bufsiz]; /* Buffer for messages Note that the port number 6969 is chosen arbitrarily, grater than 1024 and currently not in use.

The server below passes the defined constant INADDR_ANY, found in the header file <netinet/in.h> to htonl. This constant, which is mapped to the value 0, indicates to the server that any address of socket type (SOCK_STREAM) will be acceptable. /* * Internet domain, connection-oriented SERVER #include "local.h" main( void ) { int orig_sock, /* Original socket descriptor in server new_sock, /* New socket descriptor from connect clnt_len; /* Length of client address static struct sockaddr_in clnt_adr, /* Internet address of client & server serv_adr; static char buf[bufsiz]; /* Buffer for messages int len, i; /* Misc counters, etc. if ((orig_sock = socket(af_inet, SOCK_STREAM, 0)) < 0) {/* SOCKET perror("generate error"); exit(1); memset( &serv_adr, 0, sizeof(serv_adr) ); /* Clear it out serv_adr.sin_family = AF_INET; /* Set address type serv_adr.sin_addr.s_addr = htonl(inaddr_any); /* Any interface serv_adr.sin_port = htons(port); /* Use our fake port /* BIND if (bind( orig_sock, (struct sockaddr *) &serv_adr, sizeof(serv_adr)) < 0){ perror("bind error"); close(orig_sock); exit(2); if (listen(orig_sock, 5) < 0 ) { /* LISTEN perror("listen error"); exit(3); do { clnt_len = sizeof(clnt_adr); if ((new_sock = accept( orig_sock, (struct sockaddr *) &clnt_adr, &clnt_len)) < 0) { /* ACCEPT perror("accept error"); close(orig_sock); exit(4); if ( fork( ) == 0 ) { /* In CHILD process while ( (len=read(new_sock, buf, BUFSIZ)) > 0 ){

for (i=0; i < len; ++i) /* Change the case buf[i] = toupper(buf[i]); write(new_sock, buf, len); /* write it back if ( buf[0] == '.' ) break; /* are we done yet? close(new_sock); /* In CHILD process exit( 0 ); else close(new_sock); /* In PARENT process while( 1 ); /* FOREVER /* * Internet domain, connection-oriented CLIENT #include "local.h" main( int argc, char *argv[] ) { int orig_sock, len; static struct sockaddr_in serv_adr; struct hostent *host; if ( argc!= 2 ) { fprintf(stderr, "usage: %s server\n", argv[0]); exit(1); host = gethostbyname(argv[1]); /* GET INFO if (host == (struct hostent *) NULL ) { perror("gethostbyname "); exit(2); memset(&serv_adr, 0, sizeof( serv_adr)); /* Clear it out serv_adr.sin_family = AF_INET; memcpy(&serv_adr.sin_addr, host->h_addr, host->h_length); serv_adr.sin_port = htons( PORT ); if ((orig_sock = socket(af_inet, SOCK_STREAM, 0)) < 0) { /* SOCKET perror("generate error"); exit(3); /* CONNECT if (connect(orig_sock, (struct sockaddr *)&serv_adr, sizeof(serv_adr)) < 0) { perror("connect error"); exit(4); do { write(fileno(stdout),"> ", 3); /* Prompt the user if ((len=read(fileno(stdin), buf, BUFSIZ)) > 0) { /* Get user input

write(orig_sock, buf, len); /* Write to socket if ((len=read(orig_sock, buf, len)) > 0 ) /* If returned write(fileno(stdout), buf, len); /* display it. while( buf[0]!= '.' ); close(orig_sock); exit(0); The client program expects the name of the server to be passed in the command line. It then expects a message to be entered on the command line, sends this message to the server. The server changes the case and sends it back to the client. The client displays the received message.

5 Sockets The Connectionless Paradigm The server executes the following sequence of calls: socket( ) bind( ) recvfrom( ) sendto( ) The client executes the following sequence of calls: socket( ) bind( ) sendto( ) recvfrom( )

Note that the client also needs to bind socket in this case. Moreover, listen and accept are not used by the server and connect is not used by the client. The sendto network call has several alternatives: int send( char *msg, ); int socket, const int len, int flags int sendto( int socket, constchar *msg, int len, int flags,

sockaddr *to, const struct int tolen ); int sendmsg( int socket, const struct msghdr *msg, int flags ); The send network call can only be used with connected sockets. The other two can be used with both kind of sockets. The first two send sequence of bytes. The last one can do scatter-gather i/o with the struct and struct msghdr { caddr_t msg_name; int msg_namelen; struct iovec *msg_iov; int msg_iovlen; caddr_t msg_accrights; int msg_accrightslen; ; typedef struct iovec { caddr_t iov_base; int iov_len; iovec_t;

If sendto is used with connected sockets, the last two arguments are ignored. Note that there are linker specifications as lnsl and - lsocket. All of the above calls return the number of bytes sent. The following calls are alternatives for receiving. All of them return the number of bytes received and block if nothing to read. int recv( *buffer, ); int recvfrom( *buffer, flags, sockaddr *from, int socket, char int len, int flags int socket, char int len, int const struct int *fromlen ); int recvmsg( int socket, const struct msghdr *msg, int flags ); The usage of the above calls are the same as that of send calls respectively.

5.1 A Unix Domain Datagram Socket Example The client generates 10 messages and sends them to the server. The server displays the messages. They use sendto and recvfrom network calls for communication. /* SERVER - UNIX domain - connectionless #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> /* as we are using UNIX protocol #define SERVER_FILE "server_socket" main( void ) { int orig_sock, /* Original socket descriptor in server clnt_len, /* Length of client address i; /* Loop counter static struct sockaddr_un clnt_adr, /* UNIX addresses of client and server serv_adr; static char buf[10]; /* Buffer for messages void clean_up( int, char *); /* Close socket and remove it routine if ((orig_sock = socket(af_unix, SOCK_DGRAM, 0)) < 0) {/* SOCKET perror("generate error"); exit(1); serv_adr.sun_family = AF_UNIX; /* Set tag appropriately strcpy(serv_adr.sun_path,server_file);/* Assign name unlink( SERVER_FILE); /* Remove leftovers if (bind( orig_sock, (struct sockaddr *) &serv_adr, /* BIND sizeof(serv_adr.sun_family)+strlen(serv_adr.sun_path)) < 0) { perror("bind error"); clean_up(orig_sock, SERVER_FILE); exit(2); for (i = 1; i <= 10; i++) { recvfrom(orig_sock, buf, sizeof(buf), 0, /* RECEIVE it (struct sockaddr *) &clnt_adr, &clnt_len); printf("s-> %s", buf); clean_up(orig_sock, SERVER_FILE); exit(0);

void clean_up( int sd, char *the_file ){ close( sd ); unlink( the_file ); /* CLIENT - UNIX domain - connectionless #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #define SERVER_FILE "server_socket" main( void ) { int orig_sock, i; static struct sockaddr_un clnt_adr, serv_adr; static char buf[10], client_file[15]; void clean_up( int, char * ); serv_adr.sun_family = AF_UNIX; strcpy(serv_adr.sun_path, SERVER_FILE); if ((orig_sock = socket(af_unix, SOCK_DGRAM, 0)) < 0) { perror("generate error"); exit(1); sprintf(client_file,"%07d_socket",getpid()); clnt_adr.sun_family = AF_UNIX; strcpy(clnt_adr.sun_path, client_file); if (bind( orig_sock, (struct sockaddr *) &clnt_adr, /* BIND sizeof(clnt_adr.sun_family)+strlen(clnt_adr.sun_path)) < 0) { perror("bind error"); exit(2); for (i=1; i <= 10; i++) { sleep(1); /* slow down the client sprintf(buf, "c: %d\n", i); /* create message sendto(orig_sock, buf, sizeof(buf), 0, /* SEND it (struct sockaddr *) &serv_adr, sizeof(struct sockaddr)); clean_up( orig_sock, client_file); exit(0);

void clean_up( int sd, char *the_file ){ close( sd ); unlink( the_file );

5.2 An Internet Domain Datagram Socket Example Both the client and server run on separate windows. Server is run first and it displays the port number. In the command line, the client is passed the name of the host. The user enters a message to client. The client sends this message to the server which displays this message. Then a response to this message is entered to the server which in turn sends this to the client and the client displays the message. The client terminates with a ^D, server is removed with a kill command. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> static char buf[bufsiz]; /* Buffer for messages /* * Program 10.10 - SERVER - Internet Domain - connectionless #include "local.h" main( void ) { int sock, n, server_len, client_len; struct sockaddr_in server, /* Address structures client; /* create the SOCKET if ((sock = socket(af_inet, SOCK_DGRAM, 0)) < 0) { perror("server socket "); exit(1); /* set svr adr info server.sin_family = AF_INET; /* Address family

server.sin_addr.s_addr = htonl(inaddr_any); /* use any address server.sin_port = htons(0); /* pick a free port /* BIND the socket if (bind(sock, (struct sockaddr *) &server, sizeof(server) ) < 0) { perror("server bind "); exit(2); /* obtain chosen adr if (getsockname(sock, (struct sockaddr *) &server, &server_len) < 0) { perror("server getsocketname "); exit(3); /* display port # printf("server using port %d\n", ntohs(server.sin_port)); while ( 1 ) { client_len = sizeof(client); /* estimate length memset(buf, 0, BUFSIZ); /* clear the buffer if ((n=recvfrom(sock, buf, BUFSIZ, 0, /* the clnt message (struct sockaddr *) &client, &client_len)) < 0){ perror("server recvfrom "); close(sock); exit(4); write(fileno(stdout), buf, n); /* show msg to server memset(buf, 0, BUFSIZ); /* clear the buffer if (fgets(buf, BUFSIZ, stdin)!= NULL ){ /* get server's msg if ((sendto(sock, buf, strlen(buf),0, /* send it to client (struct sockaddr *) &client, client_len)) <0){ perror("server sendto "); close(sock); exit(5); /* Program 10.11 - CLIENT - Internet Domain - connectionless #include "local.h" main(int argc, char *argv[]){ int sock, n, server_len; static struct sockaddr_in /* Address structures server, client; struct hostent *host; /* For host info

if ( argc < 3 ) { /* need server & port fprintf(stderr, "usage: %s server port_#\n", argv[0]); exit(1); if (!(host=gethostbyname(argv[1]))){ /* get server info perror("client gethostname "); exit(2); /* set svr adr info server.sin_family = AF_INET; /* address family memcpy(&server.sin_addr, host->h_addr, host->h_length); /* act adr server.sin_port = htons(atoi(argv[2])); /* @ passed in port # /* create a SOCKET if ((sock=socket(af_inet, SOCK_DGRAM, 0)) < 0 ) { perror("client socket "); exit(3); /* set clnt adr info client.sin_family = AF_INET; /* address family client.sin_addr.s_addr = htonl(inaddr_any); /* use any address client.sin_port = htons( 0 ); /* pick a free port /* BIND the socket if (bind(sock, (struct sockaddr *) &client, sizeof(client)) < 0) { perror("client bind "); exit(4); while( fgets(buf, BUFSIZ, stdin)!= NULL ){ /* get clnt's msg server_len=sizeof(server); /* guess at length if (sendto( sock, buf, strlen(buf), 0, /* send msg to server (struct sockaddr *) &server, server_len) < 0 ){ perror("client sendto "); close(sock); exit(5); memset(buf,0,bufsiz); /* clear the buffer if ((n=recvfrom(sock, buf, BUFSIZ, 0, /* server's message (struct sockaddr *) &server, &server_len)) < 0){ perror("client recvfrom "); close(sock); exit(6); write(fileno(stdout),buf,n); /* show msg to clnt memset(buf,0,bufsiz); /* clear the buffer close(sock); exit(0);

The define constant INADDR_ANY is a wild card address that indicates to the server that it can use any valid address. The getsockname system call is used to determine which port the system has selected since the port number is passed value 0 to let the system pick an port that is not in use. fgets system call is used to obtain user input.