Network Application Programming The Application ...tom/413/notes/socket_API.pdf · • application...

24
Socket API2: Application Layer 1 Network Application Programming Introduction: issues Sockets: programming and implementation Other API’s: winsock java transport layer interface (TLI) Novell netware API Socket API2: Application Layer 2 The Application Programming Interface: API Definition : an API consists of the: programming model, application callable services AND interfaces, and abstractions provided by the network (i.e., lower layers of stack) to the application. What does an API provide : naming and service location ?: must application know precise location of service? e.g. host address and port Can services be requested by name? Can servers register services that they provide? connection management ? must applications do low-level handshaking required to setup / teardown connection? Socket API2: Application Layer 3 The API (continued) Does an API provide for: Message transfer ? application-selectable data transfer services: best-effort versus reliable? message priorities? multi-site atomic actions? e.g. deliver everywhere or nowhere; all at same time;... structured versus byte-stream communication? Communication flexibility ? can application select and/or modify protocol stacks (statically or dynamically)? Quality of Service specification ? can application specify QoS requirements to network ? ? Socket API2: Application Layer 4 Sockets and UNIX I/O Standards do not specify how application will interface with the protocols. interface architecture is not standardized, its design is outside the scope of the protocol suite most often, interface details depend on the operating system in use UNIX development (60’s and 70’s) had each application program execute as a user level process. application program interacted with OS via a system call system calls behave like other procedure calls take arguments and return one or more results arguments can be values or pointers to objects e.g. a buffer to be read or filled with characters UNIX I/O follows paradigm of open-read-write-close ( from MULTICS and earlier OS’s)

Transcript of Network Application Programming The Application ...tom/413/notes/socket_API.pdf · • application...

Socket API2: Application Layer 1

Network Application Programming

Introduction: issues

Sockets: programming and implementation

Other API’s:• winsock• java• transport layer interface (TLI)• Novell netware API

Socket API2: Application Layer 2

The Application Programming Interface: API• Definition : an API consists of the:

• programming model, • application callable services AND• interfaces, and abstractions

provided by the network (i.e., lower layers of stack) to the application.

• What does an API provide :• naming and service location ?:

• must application know precise location of service? • e.g. host address and port

• Can services be requested by name? • Can servers register services that they provide?

• connection management ?• must applications do low-level handshaking required to setup /

teardown connection?

Socket API2: Application Layer 3

The API (continued)Does an API provide for:• Message transfer ?

• application-selectable data transfer services: best-effort versus reliable?

• message priorities? • multi-site atomic actions?

• e.g. deliver everywhere or nowhere; all at same time;... • structured versus byte-stream communication?

• Communication flexibility ?• can application select and/or modify protocol stacks (statically

or dynamically)?

• Quality of Service specification ?• can application specify QoS requirements to network? ?

Socket API2: Application Layer 4

Sockets and UNIX I/OStandards do not specify how application will interface with the protocols.

interface architecture is not standardized, its design is outside the scope of the protocol suitemost often, interface details depend on the operating system in use

UNIX development (60’s and 70’s) had each application program execute as a user level process.

application program interacted with OS via a system callsystem calls behave like other procedure calls

take arguments and return one or more resultsarguments can be values or pointers to objects

e.g. a buffer to be read or filled with charactersUNIX I/O follows paradigm of open-read-write-close

( from MULTICS and earlier OS’s)

Socket API2: Application Layer 5

UNIX I/OBefore a process performs I/O operations -

it calls open to specify the file or device to be used and obtains permission

the call to open returns a small integer file descriptor the process uses when performing the I/O operations on the opened file or device

once opened, user makes one or more calls to read or write to transfer data

both read and write take 3 arguments that specify :file descriptor to useaddress of a buffernumber of bytes to transfer

after all transfer operations are completed, the user calls close to inform the OS it is finished with the object

Socket API2: Application Layer 6

BSD UNIX and Network ProtocolsBSD developers decided that the complexity of network protocols required more power and flexibility than the early I/O models provided

programmers needed to create server code that both waits passively as well as code that forms connections activelyapplications sending datagrams may wish to specify destination address along with each datagram rather than binding destinations at the time they call open

To deal with these observations, they chose to abandon the traditional I/O paradigm and to add several new OS calls and newlibrary routines to BSD UNIX

this increased the Unix I/O complexity

The basis for network I/O in BSD UNIX is centered on the abstraction known as the socket • introduced in 1981 BSD 4.1 UNIX

• ( Bill Joy, a founder of SUN Computer)

Socket API2: Application Layer 7

Application 1

Socket

socket interface

user

kernel

Application 2

user

kernel

Underlying communication

Protocols

Underlying communication

Protocols

Communications network

Socket

socket interface

Figure 2.16Copyright ©2000 The McGraw Hill Companies Leon-Garcia & Widjaja: Communication Networks

Socket API2: Application Layer 8

The SOCKET API

Definition :a socket is a host-local, application created & owned, OS-controlled

interfaceinto/from which the application process sends

and receives messages to/from another (remote or local) application process

Socket API2: Application Layer 9

The SOCKET API• Definition :a socket is a host-local, application

created/owned, OS-controlled interface into which the application process can both send and receive messagesto/from another (remote or local) application process

• two sockets on separate hosts “connected” by OS socket management routines.

• Application only sees local socket.Socket API2: Application Layer 10

Socketsthink of a socket as a generalization of the UNIX file access mechanismapplication programs request the OS to create a socket when one is neededsystem returns a small integer that applications use to reference the newly created socket

in this case however, the OS binds a file descriptor to a specific file or device when the application calls open but it can do so without binding them to specific destination addressesthe application chooses the destination address each time it uses the socket

e.g. when sending datagramsor it can choose to bind the destination address to the socket and avoid necessity of repeatedly specifying address

e.g. a TCP connectioncan also be used for traditional read - write operations

Socket API2: Application Layer 11

The SOCKET API (cont)

• sockets explicitly created, used and then released by applications

• based on client/server paradigm

• two types of transport service via socket API:• unreliable datagram • reliable, stream-oriented

• presentation, session layers ( from the OSI stack) are missing in UNIX networking

an application must be concerned with some details.

Socket API2: Application Layer 12

Sockets: conceptual view

• each socket has :• separate send/receive buffers, • port id, • parameters (application query- able and set- able).

• socket operations are implemented as system calls into OS

• user/kernel boundary crossed:• Overhead cost

Socket API2: Application Layer 13

Sockets: conceptual view

Socket API2: Application Layer 14

Create an endpoint for communication#include <sys/socket.h>#include <netinet/in.h>int socket (af, type, protocol)int af;int type;int protocol;

where:af Address family (domain)type Type of service desiredprotocol Optional protocol id (usually 0)

possible family valuesAF_UNIX local host domainAF_INET internet domain

possible service type valuesSOCK_STREAM reliable delivery socketSOCK_DGRAM datagram socketSOCK_RAW access to internal network

returns: channel number on success, or -1on error

Socket API2: Application Layer 15

Initiate a connection on a socket#include <sys/socket.h>#include <netinet/in.h>#include <sys/un.h>int connect (s, name, namelen)int s;const struct sockaddr * name;int namelen;

where:s The file descriptor of a socket to connectname Name of peer or listening socket through which the connection

will be made name = pointer to structure containing IP ADDR & PORT # of DEST

namelen Length of name (bytes)( in IP v4 = 4 )

possible name address formatsstruct sockaddr_in{short sin_family; /* AF_INET */u_short sin_port; /* port number */struct in_addr sin_addr; /* inet addr */char sin_zero[8]; }

returns: 0 on success, or -1 on errorSocket API2: Application Layer 16

Connectionless Service• datagram service: underlying transport protocols

do not guarantee delivery

• no explicit identification of who is server, who is client

• if initiating contact with other side, need to know• IP address• port number of process waiting to be contacted.

• if waiting for contact from other side, someone needs to declare :• port number at which you are waiting for other side to

send data

Socket API2: Application Layer 17

socket()

bind()

listen()

read()

close()

socket()

connect()

read()

write()

close()

blocks until server receivesa connect request from client

data

data

Server

Clientaccept()

write()

Figure 2.17Leon-Garcia & Widjaja: Communication NetworksCopyright ©2000 The McGraw Hill Companies

TCP socket calls

Blocks until server receives a connect request from client connect negotiation

ok

Socket API2: Application Layer 18

socket()

bind()

sendto()

close()

socket()

bind()

recvfrom()

sendto()

close()

blocks until serverreceives data from client data

data

Server

Client

recvfrom()

Figure 2.18Leon-Garcia & Widjaja: Communication NetworksCopyright ©2000 The McGraw Hill Companies

UDP socket calls

Socket API2: Application Layer 19 Socket API2: Application Layer 20

Creating a socketSocket system call

creates sockets on demandTakes 3 integer arguments and returns an integer result :result = socket ( pf, type, protocol )pf - specifies the protocol family to be used with the socket

– i.e how to interpret addresses when suppliedtype argument specifies the type of

communication desiredprotocol argument allows further flexibility

Socket API2: Application Layer 21

Creating a socket• same endpoint (socket) is used to send/receive data• no a priori association of socket with network• must specify transport protocol family, and specific transport-

level service to be used with socket:Protocol Family symbolic name

TCP/IP Internet AF_INET Xerox NS AF_NS intra-host UNIX AF_UNIX DEC DNA AF_DECNET

service type symbolic name comment

datagram SOCK_DGRAM UDP protocol in AF_INET reliable, in-order SOCK_STREAM TCP protocol in AF_INET raw socket SOCK_RAW direct access to network layer

Socket API2: Application Layer 22

Creating a socket (cont.)int socket ( int family, int service, int protocol)

• family is symbolic name of protocol family • service is symbolic name of service type• protocol allows further specification of raw socket.

For us, this will be 0.

• return code from socket( ) is a socket descriptor, used in all remaining socket-related system calls

Example:#include <sys/types.h>#include<sys/ socket.h>

int sockfd; if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

{ /* handle error */ }

Socket API2: Application Layer 23

System Calls for Elementary TCP Sockets#include <sys/types.h>#include <sys/socket.h>

family: specifies the protocol family {AF_INET for TCP/IP}type: indicates communications semantics

SOCK_STREAM stream socket TCPSOCK_DGRAM datagram socket UDPSOCK_RAW raw socket

protocol: set to 0 except for raw sockets

returns on success: socket descriptor {a small nonnegative integer}on error: -1

Example:If (( sockfd = socket (AF_INET, SOCK_STREAM, 0)) < 0)

err_sys (“socket call error”);

socket Functionint socket ( int family, int type, int protocol )

2: Application Layer 24

Internet Addressing• each Internet host has one or more globally-unique

32-bit IP addresses

• host may have multiple (two or more) addresses• Unique address is associated with each interface card

• dotted decimal notation: • 4 decimal integers, each specifying one byte of an IP address:

host name cs.uml.edu32-bit address 10000001 00111111 00000001 00000111

dotted decimal 129.63.1.6

• library procedure inet_addr() converts dotted-decimal address string to a 32-bit address

• library procedure gethostbyname() converts textual name to 32 bit address.

Socket API2: Application Layer 25

The Internet Domain System Structure• hierarchical administering of names

• e.g.: cs.uml.edu• leftmost name is typically a host name (has an IP address)• next leftmost name is organization administering that host

(e.g., UML C.Sc. Dept.)• next leftmost name is organization administering all of

subnames to the left • rightmost (highest) domain: organization, structure,

country

domain usage example com business watso n .i b m.c o m edu educational cs.umas s .ed u gov US non - mi l itar y gov't whitehous e .gov mil US mil i tary arpa .mi l org non -prof i t org a niza t ion npr.org net network resources nis.n s f.net jp Japan osaka -u.ac. jp

Socket API2: Application Layer 26

DNS: Internet Domain Name System•• a a distributed database distributed database used by TCP/IP applications to used by TCP/IP applications to

map to/from hostnames from/to IP addressesmap to/from hostnames from/to IP addresses•• name servers :name servers :

•• useruser--level library routines level library routines gethostbynamegethostbyname()() and and gethostbyaddressgethostbyaddress()() contact the local name server via contact the local name server via port 53port 53

•• name server returns IP address of requested hostnamename server returns IP address of requested hostname

Socket API2: Application Layer 27

DNS: non-local names

finding non-local namesno single name server has complete information table

if local name server can't resolve address, contacts root name server:• 13 redundant root nameservers world-wide• each has addresses of names servers for all level-two name

servers (e.g., uml.edu, ibm.com)• contacted root server returns IP address of name server

resolver should contact• contacted level-two name server may itself return a pointer to

another name server • name resolution an iterative process of following name server

pointers• DNS protocol specifies packet formats for exchanges with

DNS serversSocket API2: Application Layer 28

Assigning a socket a network address: bind()• each socket must be associated with a

1. local, 2. host-unique 3. 16-bit port number..

• need to associate socket with globally unique network address(host address and port) so that

• OS knows that incoming messages addressed to this host address and port are to be delivered to (demultiplexed to) this socket . Incoming are from a specific remote port and IP address

• a return address for outgoing messages

• port is a local association while network address is global

Socket API2: Application Layer 29

Assigning a socket a network address

Port number(s) comment 1 - 255 reserved for standard services 21 ftp service 23 telnet service 25 SMTP email 80 http daemon 1 - 1023 available only to privileged users 1024 - 4999 usable by system and user

processes 5000 - usable only by user processes

Socket API2: Application Layer 30

Byte Ordering Routines

byte ordering routines:

• convert to/ from host 16- and 32-bit integers from/to ``network byte order'‘

• different computers store bytes of an integer in different order in memory

• internal representation of 2^{24}

• network byte order is big - endian

• integer quantities (such as addressing info) should be explicitly converted to/from network byte order (nbo). • Use system provided macros• for both sending and receiving

Socket API2: Application Layer 31

Big Endian/Little Endian

Socket API2: Application Layer 32

UNIX Procedures

Function name

action

htonl convert 32-bit host format to nbo ntohl convert nbo to 32-bit host format htons convert 16-bit host format to nbo ntohs convert nbo to 16-bit host format

Socket API2: Application Layer 33

Other useful system calls and routines

• close(sockfd) will release a socket

• getsockopt() and setsockopt()system calls used to query/set socket options.

• ioctl() system call used to query/set socket attributes, also network device interface attributes.

Socket API2: Application Layer 34

Socket addressing: predefined address structuresspecifying socket addresses: certain data structures predefined for you:

struct sockaddr_in { /* INET socket addr info */ short sin_family; /* set me to AF_INET */ u_short sin_port; /* 16 bit number, nbo */

struct in_addr sin_addr; /* 32 bit host address */ char sin_zero[8]; /* not used */

}; struct in_addr {

u_long s_addr; /* 32 bit host addr,nbo */};

** nbo == network byte order may need to convert before sending into socket

family,port

&

IP

Socket API2: Application Layer 35

The bind() system call

int bind ( int sockfd, struct sockaddr *myaddr, int addresslen)

• sockfd is the variable assigned socket() return value.

• *myaddr: address of sockaddr_in structure holding local address info. Must be cast to type sockaddr.

• addresslen is the size of the address structureerror return indicates port number already in use, out-of-range

Socket API2: Application Layer 36

Filling the sockaddr_in structure (II) • INADDR_ANY is used for accepting connections on any local interface if the system is multi-homed

• Assign a zero port number when filling the sockaddr_indata structure, if we want a free port to be allocated to asocket during the bind() procedure

• htonl(), htons() handle byte-ordering differences between computerarchitectures and network protocols

>> redundant in Sun’s sparc>> needed in x86 architectures

Socket API2: Application Layer 37

Filling the sockaddr_in structure (I) Example I:

sock_addr.sin_addr.s_addr = inet_addr(“128.59.69.7”);sock_addr.sin_port = htons(5115);sock_addr.sin_family = AF_INET;

Example II:

sock_addr.sin_addr.s_addr = htonl(IN_ADDR_ANY);sock_addr.sin_port = htons(0);sock_addr.sin_family = AF_INET;

Socket API2: Application Layer 38

The socket() function int socket(int family, int type, int protocol)

Example:

if (( sock = socket(AF_INET,SOCK_STREAM,0)) == -1) { printf(": error opening socket");

exit(-1);}

-Creates a socket: Not associated with a client or server process yet

- SOCK_STREAM vs. SOCK_DGRAM

Socket API2: Application Layer 39

The bind() function int bind(int sockfd, struct sockaddr *myaddr, int addrlen)

Example:

if ( bind(sock, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) < 0) { printf(": error binding socket to local address");

exit(-1);}

- Binds a socket to an IP address and port.Not associated with a client or server process yet

Socket API2: Application Layer 40

The bind() system call (cont)#include <sys/types.h>#include <sys/socket.h>#include "inet.h”int sockfd;struct sockaddr_in myaddr;if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)

{ /* handle error */ }myaddr.sin_family = AF_INET;myaddr.sin_port = htons(5100); /* > 5000myaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* INADDR lets OS determine hostid */if ( bind(sockfd, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0)

{ /* handle error */ }

Convert to net byte order

Socket API2: Application Layer 41

Example: connectionless server1 #include <stdio.h>2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 #include <errno.h> 7 #define MY_PORT_ID 6090 /* a number > 5000 */ 89 main() 10 { 11 int sockid, nread, addrlen; 12 struct sockaddr_in my_addr, client_addr; 13 char msg[50]; 14

Socket API2: Application Layer 42

connectionless server, cont.

15 printf("Server: creating socket\n"); 16 if ( (sockid = socket (AF_INET, SOCK_DGRAM, 0)) < 0){ 17 printf("Server: socket error: %d\n",errno); exit(0);} 18 printf("Server: binding my local socket\n"); 19 bzero((char *) &my_addr, sizeof(my_addr)); 20 my_addr.sin_family = AF_INET; 21 my_addr.sin_addr.s_addr = htons(INADDR_ANY); 22 my_addr.sin_port = htons(MY_PORT_ID);

Fill in my_addr

Socket API2: Application Layer 43

Example: connectionless server (cont)

23 if ( (bind(sockid, (struct sockaddr *) &my_addr,24 sizeof(my_addr)) < 0) )25 {printf("Server: bind fail: %d\n",errno); exit(0);}26 printf("Server: starting blocking message read\n");27 nread = recvfrom(sockid,msg,11,0, 28 (struct sockaddr *) &client_addr, &addrlen);29 printf("Server: return code from read is %d\n", nread); 30 if (nread >0) printf("Server: message is: %.11s\n” ,msg);31 close(sockid); 32 }

Socket API2: Application Layer 44

Example: connectionless client1 #include <stdio.h>2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 #include <errno.h> 7 #define MY_PORT_ID 6089 8 #define SERVER_PORT_ID 6090 9 #define SERV_HOST_ADDR "128.119.40.186" 10 11 main() 12 {

Socket API2: Application Layer 45

13 int sockid, retcode; 14 struct sockaddr_in my_addr, server_addr; 15 char msg[12]; 16 17 printf("Client: creating socket\n"); 18 if ((sockid = socket(AF_INET, SOCK_DGRAM, 0)) < 0){ 19 printf("Client: socket failed: %d\n",errno); exit(0);} 2021 printf("Client: binding my local socket\n");22 bzero((char *) &my_addr, sizeof(my_addr));23 my_addr.sin_family = AF_INET; 24 my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 25 my_addr.sin_port = htons(MY_PORT_ID); 26 if ( ( bind(sockid, (struct sockaddr *) &my_addr, 27 sizeof(my_addr)) < 0) )28 { printf("Client: bind fail: %d\n",errno);exit(0);}29

connectionless client,cont.1

Socket API2: Application Layer 46

connectionless client , 230 printf("Client: creating addr structure for

server\n");31 bzero((char *) &server_addr, sizeof(server_addr)); 32 server_addr.sin_family = AF_INET; 33 server_addr.sin_addr.s_addr =

inet_addr(SERV_HOST_ADDR); 34 server_addr.sin_port = htons(SERVER_PORT_ID); 35 36 printf("Client: initializing message and

sending\n"); 37 sprintf(msg, "Hello world"); 38 retcode = sendto(sockid,msg,12,0,

(struct sockaddr *)&server_addr,39 sizeof(server_addr)); 40 if (retcode <= -1){ 41 printf("client: sendto failed: %d\n",errno);exit(0);} 42 43 /* close socket */ 44 close(sockid); 45 }

Socket API2: Application Layer 47

Example: execution trace

> cc udpserver.c; mv a.out udpserver> cc udpclient.c; mv a.out udpclient> udpserver &[1] 20837

> Server: creating socketServer: binding my local socketServer: starting blocking message read > udpclient

Client: creating socketClient: binding my local socketClient: creating addr structure for server Client: initializing message and sending Server: return code from read is 11Server: message is: Hello world[1] Done udpserver Socket API2: Application Layer 48

Connection-oriented service

Socket API2: Application Layer 49

SERVER

assign address to transport endpoint:bind()

CLIENTcreate transportendpoint: socket()

assign transportendpoint an address(optional) :bind()

announce willing toaccept connections: listen()

block/wait for incoming conn. req.:accept()(new socket created on return)

wait for pkt:recvfrom()

send reply (if any):sendto()

connect to server via socket: connect()

release transportendpoint:close()

send msg: sendto()

wait for reply:recvfrom()

create transport endpoint:socket()for incoming requests

release transportendpoint:close()

determine addr. of servermsg exchangeand synch.

request

reply

Socket API2: Application Layer 50

Connection-oriented service

• client/server handshaking: • client must explicitly connect to server before sending

or receiving data (unlike connectionless service case)• client will not pass connect() until server accepts client • server must explicitly accept client before sending or

receiving data • server will not pass accept() until client connect()'s

• connection-oriented service: underlying transport service is reliable and stream-oriented.

Socket API2: Application Layer 51

Client-to-server connection: connect()• client uses connect() to request connect to server

and communication via socket

• underlying transport protocol (e.g. TCP) begins connection setup protocol implementing client/server handshake

• connect() returns when server explicitly accepts connection, or timeout (no server response)

• typically used with reliable transport protocols, but also with datagrams

Socket API2: Application Layer 52

Client-to-server connection: connect()

int connect ( int sockfd, struct sockaddr*toaddrptr, int addresslen)

• sockfd: variable assigned socket() return value. Process accepts incoming connections on this socket id.

• *toaddrptr is address of sockaddr_instructure holding server address info. Must be cast to type sockaddr.

• addresslen is the size of address structure

Socket API2: Application Layer 53

The listen() system call

• used by connection-oriented server

• let network/OS know server will accept connection requests

• does not block and does not wait for request!

• int listen ( int sockfd, int maxwaiting)

• sockfd: variable assigned socket() return value. Process accepts incoming connections on this socket id.

• maxwaiting: maximum number of connection requests that can be queued, waiting for server to do an accept().Typical value is 5. Typical value is 5.

Socket API2: Application Layer 54

Server-to-client connection: accept()

• done by server, after listen().

• server will accept() connection request via specified socket, and return newly created socket for use in communicating back to accept()'ed client.

• server has one socket for accepting incoming connection requests AND creates other (new) sockets for communication with clients

• server can not selectively accept() connection requests • typically handled FCFS.

Socket API2: Application Layer 55

accept(), cont

int accept ( int sockfd, struct sockaddr*fromaddrptr, int *addresslen)

• sockfd is variable assigned socket() return value.

• *fromaddrptr is address of sockaddr_instructure containing address info of socket that sent this data. A returned value.- a different socket

• addresslen is size of address structure. A value-result argument (set before call, reset during call).

Socket API2: Application Layer 56

accept(), cont

struct sockaddr_in other_app_addr;int sockid , newsockid, addrsize;

…addrsize = sizesizeof(other_app_addr));

newsockid = accept(sockfd,(struct sockaddr*)&other_app_addr, &addrsize);

/* newsockid to communicate with client, sockid to accept more connections */

Socket API2: Application Layer 57

A Simple Timing Application

Client will : • connect to server • send server client local time• read back server's local time

Server will: • receive connections from clients • print out client's local time• send client server's local time

Socket API2: Application Layer 58

A Simple Timing Application: client code

1 #include <sys/types.h>2 #include <sys/socket.h>3 #include <netinet/in.h>4 #include <arpa/inet.h>5 #include <time.h>6 #include <errno.h>7 #define SERV_HOST_ADDR "128.119.40.186" /* Don's host

machine */8 main()9 {10 int sockid;11 struct sockaddr_in ssock_addr;12 struct timeval tp;13 struct timezone tzp; 14

Socket API2: Application Layer 59

15 /* create a socket */16 if ( (sockid = socket(AF_INET, SOCK_STREAM, 0)) < 0){17 printf("error creating client

socket,error%d\n",errno);18 exit(0); 19 }2021 printf("Client: creating addr structure for server\n");22 bzero((char *) &server_addr, sizeof(server_addr)); 23 server_addr.sin_family = AF_INET; 24 server_addr.sin_addr.s_addr =

inet_addr(SERV_HOST_ADDR); 25 server_addr.sin_port = htons(SERVER_PORT_ID); 26 if (connect(sockid, (struct sockaddr *)

&server_addr, sizeof(server_addr)) < 0){27 printf("error connecting to server, error: %d\n",errno); 28 exit(0);29 }

Socket API2: Application Layer 60

30 /* send time of day */31 gettimeofday(&tp,&tzp);32 /* convert from host byte order to network byte order */33 printf("client: local time is %ld\n",tp.tv_sec);34 tp.tv_sec = htonl(tp.tv_sec);35 tp.tv_usec = htonl(tp.tv_usec);38 /* send time of day to other side */39 write(sockid, &tp, sizeof(tp));40 /* get time of day back fro other side and display */41 if ( (read(sockid, &tp, sizeof(tp))) < 0){42 printf("error reading new socket\n"); 43 exit(0); 44 }45

Socket API2: Application Layer 61

46 /* convert from network byte order to host byte order */

47 tp.tv_sec = ntohl(tp.tv_sec);48 tp.tv_usec = ntohl(tp.tv_usec);49 printf("client: remote time is %ld\n",tp.tv_sec);50 close(sockid); 51 }

Socket API2: Application Layer 62

Sending and Receiving Data

data sent/received using standard UNIX i/o system data sent/received using standard UNIX i/o system calls or networkcalls or network--specific system calls specific system calls

system call device buffering options specify peer?

read()/write() any i/o single N N readv()/writev() any i/o scatter/gather N N recv()/send() socket single Y N recvfrom()/sendto() socket single Y Y recvmsg()/sendmsg() socket scatter/gather Y Y

Socket API2: Application Layer 63

A Simple Timing Application: server code

1 #include <stdio.h>2 #include <sys/types.h>3 #include <sys/socket.h>4 #include <netinet/in.h>5 #include <arpa/inet.h>6 #include <time.h>7 #include <errno.h>8 #define MY_PORT_ID 6090 /* a number > 5000 */910 main()11 {12 int sockid, newsockid, i,j;13 struct sockaddr_in ssock_addr;14 struct timeval tp;15 struct timezone tzp;16 Socket API2: Application Layer 64

17 /* create a socket */18 if ( (sockid = socket (AF_INET, SOCK_STREAM, 0)) < 0)19 { printf("error creating socket, error: %d\n",errno); exit(0); }20 /* do a man on errno to get error information */21 /* name the socket using wildcards */22 bzero((char *) &ssock_addr,

sizeof(ssock_addr));23 ssock_addr.sin_family = AF_INET;24 ssock_addr.sin_addr.s_addr =

htonl(INADDR_ANY);25 ssock_addr.sin_port =

htons(MY_PORT_ID);26 /* bind the socket to port address */27 if ( ( bind(sockid, (struct sockaddr *) &ssock_addr, sizeof(ssock_addr)) < 0) )28 { printf("error binding socket, error: %d\n",errno); exit(0); } 29 /* start accepting connections */ 30 if ( listen (sockid, 5) < 0)31 { printf("error listening: %d\n",errno); exit(0); }32

Socket API2: Application Layer 65

33 for (i=1; i<=50000 ;i++) {34 /* accept a connection */35 newsockid = accept(sockid, (structsockaddr *)0, (int *)0);36 if (newsockid < 0)37 { printf("error accepting socket, error: %d\n",errno); exit(0); }38 /* read remote time of day from socket */39 if ( (read(newsockid, &tp, sizeof(tp))) < 0)40 { printf("error reading new socket\n"); exit(0); }41 /* convert from network byte order to host byte order */42 tp.tv_sec = ntohl(tp.tv_sec);43 tp.tv_usec = ntohl(tp.tv_usec);44 printf("server: remote time is %ld\n",tp.tv_sec);45

Socket API2: Application Layer 66

46 /* get local time of day and send to client*/47 for (j=0; j<1000000; j++)48 ; /* delay */49 gettimeofday(&tp,&tzp);50 /* convert from host byte order to network byte order */51 printf("server: local time is

%ld\n",tp.tv_sec);52 tp.tv_sec = htonl(tp.tv_sec);53 tp.tv_usec = htonl(tp.tv_usec);54 write(newsockid, &tp, sizeof(tp));55 close(newsockid);56 }57 close(sockid);58 }

Socket API2: Application Layer 67

Typical server structure

Socket API2: Application Layer 68

Server Structure: code fragment

int sockfd, newsockfd;if ( (sockfd = socket( ... )) < 0) /* create socket */

.....if ( bind(sockfd,... ) < 0) /* bind socket */.....if ( listen(sockfd,5) < 0) /* announce we're ready */.....while (1==1) { /* loop forever */newsockfd = accept(sockfd, ...); /* wait for client */

Socket API2: Application Layer 69

if ( (pid = fork()) == 0) { /* child code begins here */close(sockfd); /* child doesn't wait for client */....../* child does work here, communicating with client using

the newsockfd */.......exit(0); /* child dies here */}

/* parent continues execution below */close(newsockfd); /* parent won't communicate with *//* client - that's childsplay! */ } /* end of while */

Socket API2: Application Layer 70

sendto()int sendto (int sockfd, char *buff, intbufflen, int flags, struct sockaddr*toaddrptr, int addresslen)

•• sockfdsockfd is the variable assigned socket() return value.is the variable assigned socket() return value.

•• *buff is a set of consecutive *buff is a set of consecutive memmem. . locslocs. holding message to send. holding message to send

•• bufflenbufflen is number of bytes to sendis number of bytes to send•• flags can be used to specify options. Always 0 for us.flags can be used to specify options. Always 0 for us.

•• **toaddrptrtoaddrptr is address of is address of sockaddr_insockaddr_in structure holding destination structure holding destination address info. Must be cast to type address info. Must be cast to type sockaddrsockaddr..

•• addresslenaddresslen is the size of the address structureis the size of the address structure

•• OK return code does NOT imply data correctly delivered, only OK return code does NOT imply data correctly delivered, only correctly sent correctly sent

Socket API2: Application Layer 71

Example: using sendto()

char buffer[50];struct sockaddr_in other_app_addr;int retcode

/* suppose we have done socket() and bind() calls, filled in other_app_addr,andput 23 bytes of data into buffer */

retcode = sendto(sockfd, buffer, 23, 0, (struct sockaddr *) &other_app_addr,sizeof(other_app_addr))

Socket API2: Application Layer 72

recvfrom()int recvfrom (int sockfd, char *buff, int bufflen, int flags,

struct sockaddr *fromaddrptr, int *addresslen)

•• sockfdsockfd is variable assigned socket() return value.is variable assigned socket() return value.

•• *buff is a set of consecutive *buff is a set of consecutive memmem. . locslocs. into which received data . into which received data to be writtento be written

•• bufflenbufflen is number of bytes to readis number of bytes to read

•• flags can be used to specify options. Always 0 for us.flags can be used to specify options. Always 0 for us.

•• **fromaddrptrfromaddrptr is address of is address of sockaddr_insockaddr_in structure containing structure containing address info of socket that sent this data. A returned value.address info of socket that sent this data. A returned value.

•• addresslenaddresslen is size of address structure. A returned value.is size of address structure. A returned value.

•• recvfromrecvfrom() returns number bytes actually received () returns number bytes actually received

Socket API2: Application Layer 73

Example: using recvfrom()

char buffer[50];struct sockaddr_in other_app_addr;int nread, addrlen;

/* suppose we have done socket(), bind() */nread = recvfrom(sockfd, buffer, 23, 0,

(struct sockaddr *) &other_app_addr,

&addrlen))

Socket API2: Application Layer 74

Scatter read and gather write

used to read/write into/from multiple nonused to read/write into/from multiple non--contiguous contiguous buffersbufferswritev(int sd, struct iovec iov[], int

iovcount);

readv(int sd, struct iovec iov[], int

iovcount);struct iovec{caddr_t iov_base; /* starting addr of

this buffer */ int iov_len; /* num. bytes in this

buffer */};

Socket API2: Application Layer 75 Socket API2: Application Layer 76

Asynchronous I/O

• socket reads we have seen are blocking.

• application can be notified by OS when data ready to be read using asynchronous i/o:

• write a ``handler'' procedure: called by OS when data ready to be read

• inform OS of process id and name of procedure to be called

• enable asynchronous i/o

Socket API2: Application Layer 77

Asynchronous I/O: example

#include <signal.h>#include <fnctl.h>int datahere = 0;

main() {/* create, bind, connect/accept, etc done here */

signal(SIGIO,read_proc); /* inform OS: call read_proc when data

arrives */fnctl(sd, F_SETOWN, getpid())

/* inform OS: procedure is inside ``me'' */fnctl(sd, F_SETFL, FASYNCH)

/* enable asynchronous I/O */

Socket API2: Application Layer 78

while (1==1) {..…/ * do useful work, possibly checking datahere flag.

Note there is NO EXPLICIT CALL to read_proc() */}

}

read_proc() /* called by OS on data arrival */{datahere = 1;/* possibly do other useful work */

}

Socket API2: Application Layer 79

The select() system call

•• application may want to respond to incoming I/O (e.g., application may want to respond to incoming I/O (e.g., data, connect requests) occurring on several different data, connect requests) occurring on several different socketssockets

•• do not want to block on any single do not want to block on any single accept(), accept(), recvmsgrecvmsg()()

•• I/O multiplexing using select(): I/O multiplexing using select(): •• inform OS of set of sockets we're interested ininform OS of set of sockets we're interested in•• call select(), which won't return until I/O pending on one of call select(), which won't return until I/O pending on one of

specified socketsspecified sockets•• select() will tell us which sockets are ready for I/Oselect() will tell us which sockets are ready for I/O•• do I/O (e.g., accept(), do I/O (e.g., accept(), recvmsgrecvmsg()) on appropriate socket ()) on appropriate socket

Socket API2: Application Layer 80

The select() system call

•• macros FD_ZERO, FD_SET, FD_CLEAR, macros FD_ZERO, FD_SET, FD_CLEAR, FD_ISSET supplied by OS, used by FD_ISSET supplied by OS, used by application for declaring, determining ready application for declaring, determining ready socket(s). socket(s).

int select(int maxsockets, fd_set*readytoread,

fd_set *readytowrite, fd_set*readyexceptions,

struct timeval *timeptr);

Socket API2: Application Layer 81

The select() system call: simple example

#include <sys/types.h>main(){fd_set readset;int nready;

/* open, bind, connect/accept etc. sockets sd1, sd2, sd3 *//* tell OS sockets we're interested in */FD_ZERO(&readset);FD_SET(sd1,&readset);FD_SET(sd2,&readset);FD_SET(sd3,&readset);

Socket API2: Application Layer 82

The select() system call: simple example

/* call select, returning when something's ready */nready = select(64, &readset, NULL, NULL, NULL);/* read from appropriate socket */if (FD_ISSET(sd1, &readset)) ..... /* do i/o from sd1 */else if (FD_ISSET(sd2, &readset)) ..... /* do i/o from sd2 */else if (FD_ISSET(sd3, &readset)) ..... /* do i/o from sd3 */

Socket API2: Application Layer 83

bind assigns a local protocol address to a socket.protocol address: a 32 bit IPv4 address + a 16 bit TCP or UDP port

number.sockfd: a socket descriptor returned by the socket function.*myaddr: a pointer to a protocol-specific address.addrlen: the size of the socket address structure.Servers bind their “well-known port” when they start.returns on success: 0

on error: -1Example:If (bind (sd, (struct sockaddr *) &servaddr, sizeof (servaddr)) != 0)

errsys (“bind call error”);

bind Function

int bind (int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);

Socket API2: Application Layer 84

sockfd: a socket descriptor returned by the socket function*servaddr: a pointer to a socket address structureaddrlen: the size of the socket address structure

The socket address structure must contain the IP address and the port number for the connection wanted.

In TCP connect initiates a three-way handshake. connect returns when the connection is established or when an error occurs.

returns on success: 0on error: -1

Example:

if ( connect (sockfd, (struct sockaddr *) &servaddr, sizeof (servaddr)) != 0)

err_sys(“connect call error”);

connect Function

int connect (int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);

Socket API2: Application Layer 85

Listen is called only by a TCP server and performs two actions:1. Converts an unconnected socket into a passive socket.2. Specifies the maximum number of connections that the

kernel should queue for this socket.returns on success: 0

on error: -1Example:If (listen (sd, 2) != 0)

errsys (“listen call error”);

listen Function

int listen (int sockfd, int backlog);

Socket API2: Application Layer 86

accept is called by the TCP server to return the next completed connection from the front of the completed connection queue.

sockfd: this is the same socket descriptor as in listen call.*cliaddr: used to return the protocol address of the connected peer

process (i,e., the client process).*addrlen: {this is a value-result argument}

before the accept call: we set the integer value pointed to by *addrlen to the size of the socket address structure pointed to by cliaddr;on return from accept call: this integer value contains the actual number of bytes stored in the socket address structure.

returns on success: a new socket descriptoron error: -1

accept Function

int accept (int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);

Socket API2: Application Layer 87

For accept the first argument sockfd is the listening socketand the returned value is the connected socket.

The server will have one connected socket for each client connection accepted.

When the server is finished with a client, the connected socket must be closed.

Example:sfd = accept (s, NULL, NULL);if (sfd == -1) err_sys (“accept error”);

accept Function (cont.)

int accept (int sockfd, struct sockaddr *cliaddr, socklen_t addrlen);

Socket API2: Application Layer 88

close marks the socket as closed and returns to the process immediately.

sockfd this socket descriptor is no longer useable.Note – TCP will try to send any data already queued to the

other end before the normal connection termination sequence.

Returns on success: 0on error: -1

Example:

close (s);

close Function

int close (int sockfd);

Socket API2: Application Layer 89

Socket bind ( cont.)Bind a name to a socket

#include <sys/socket.h>#include <netinet/in.h>#include <sys/un.h>int bind (s, name, namelen)int s;const struct sockaddr * name;int namelen;

where:s Socket to bindname Name to bind to socketnamelen Length of name (bytes)

DescriptionThis call allows a process to establish a link to an underlying TCP or UDP port

(in the case of an internet socket) or a link to a path name in the file system (in the case of a UNIX domain socket). In general, a server must use this call to give herself an address, whereas a client is not required to use this call (but may if she so chooses),but is automatically allocated a source port at the time a connect() call is made. It can be seen that the call arguments are the same as those for the connect call.

returns: 0 on success, or -1Socket API2: Application Layer 90

Listen for connections on a socketint listen (s, backlog)int s;int backlog;

where:s File descriptor of socket to listen on.backlog Maximum number of waiting connections.

returns: 0 on success, or -1SYNOPSIS

#include <sys/socket.h>#include <netinet/in.h>#include <sys/un.h>int accept (s, addr, addrlen)int s;struct sockaddr * addr;int * addrlen;

where:s Socket channel listening for connection requestsaddr Structure to receive the address of connected peeraddrlen On input contains the number of bytes available for the peer address;

updated to indicate the number of bytes returnedreturns: Connected new channel number, or -1

Socket API2: Application Layer 91

Example With Internet SocketsClient/Server example using internet sockets

A "one-time" FTP client/* client.c a minimal FTP client *//* this version works on all BSD based systems */

#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <fcntl.h>#include <strings.h>

#define MSG_BODY 248#define MSG_SIZE (MSG_BODY+8)#define PORT 27439#define SEND 1#define RECV 2#define DATA 100#define END_DATA 101

typedef struct{int mtype;int msize;char mbody[MSG_BODY];

} MSG;typedef union{

MSG m;char buf[MSG_SIZE];

} MBUF;Socket API2: Application Layer 92

Client/Server example using internet socketsA "one-time" FTP clientmain(int argc, char *argv[]){

MSG msg;MBUF raw;int inet_sock, local_file;int type_val, size_val, read_val, local_size;int i,j,k;char *buffer_ptr, *token_ptr, *last_token_ptr;union type_size;struct sockaddr_in inet_telnum;struct hostent *heptr, *gethostbyname();

if((inet_sock=socket(AF_INET, SOCK_STREAM, 0)) == -1){perror("inet_sock allocation failed: ");exit(1);

}

if((heptr = gethostbyname( argv[1] )) == NULL){perror("gethostbyname failed: ");exit(1);

}bcopy(heptr->h_addr, &inet_telnum.sin_addr, heptr->h_length);inet_telnum.sin_family = AF_INET;inet_telnum.sin_port = htons( (u_short)PORT );if(connect(inet_sock, &inet_telnum, sizeof(struct sockaddr_in)) == -1){

perror("inet_sock connect failed: ");exit(2);

Socket API2: Application Layer 93

Client/Server example using internet sockets cont'dA "one-time" FTP client

msg.mtype = htonl(RECV);strcpy(msg.mbody, argv[2]);local_size = strlen(argv[2]) +1;msg.msize = htonl(local_size);

token_ptr = strtok(argv[2], "/");do{

if((last_token_ptr = token_ptr) == NULL){printf("\n *** Illegal path name, terminating\n\n");exit(2);

}} while(token_ptr = strtok(NULL, "/"));

if((local_file=open(last_token_ptr, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1){

perror("local_file open failed: ");exit(3);

}if(write(inet_sock, &msg, local_size + (2*sizeof(int))) == -1){

perror("inet_sock write failed: ");exit(3); Socket API2: Application Layer 94

Client/Server example using internet sockets cont'dA "one-time" FTP clientwhile(1){

for(i=0; i<(2*sizeof(int)); i++){if(read(inet_sock, raw.buf+i, 1) != 1){

perror("read type_size failed: ");exit(3);

}}

type_val = ntohl(raw.m.mtype);size_val = ntohl(raw.m.msize);read_val = size_val;buffer_ptr = raw.buf;switch(type_val){

case DATA:while ((j = read(inet_sock, buffer_ptr, read_val)) != read_val){

switch(j){default: read_val -= j;

buffer_ptr +=j;break;

case -1: perror("inet_sock read failed: ");exit(3);

case 0: printf("unexpected EOF on inet_sock\n");exit(4);

}}if(write(local_file, raw.buf, size_val) == -1){

perror("local write failed: ");exit(3);}break;

case END_DATA:printf("transfer of %s completed successfully, goodbye\n",argv[2]);exit(0);

default:printf("unknown message type %d size of %d\n",type_val,size_val);printf("this is an unrecoverable error, goodbye\n");exit(5);

}}