Network application programming
Download
1 / 80

Network Application Programming - PowerPoint PPT Presentation


  • 119 Views
  • Uploaded on

Network Application Programming. Introduction: issues Sockets: programming and implementation Other API’s: winsock java transport layer interface (TLI) Novell netware API. The Application Programming Interface: API.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Network Application Programming' - tuari


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Network application programming
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


The application programming interface api
The Application Programming Interface: API

  • Definition : an API is the programming model, application callable services, interfaces, and abstractions provided by the network (i.e., lower layers) to the application.

  • does an API provide for:

    • naming and service location:

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

      • Can services be requested by name?

      • Can servers registers services?

    • connection management

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

Socket API2: Application Layer


The api continued
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


Sockets and unix i o
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) has each application program execute as a user level process.

    • application program interacts with OS via a system call

    • system calls behave like other procedure calls -i.e. 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 )

Socket API2: Application Layer


Unix i o
UNIX I/O

  • Before 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 use

        • address of a buffer

        • number 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


Bsd unix and network protocols
BSD UNIX and Network Protocols

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

    • programmers needed to create both server code that waits passively as well as code that forms connections actively

    • applications 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 new library 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, founder of SUN)

Socket API2: Application Layer


The socket api
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 messages to/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


Sockets
Sockets

  • think of a socket as a generalization of the UNIX file access mechanism

  • application programs request the OS to create a socket when one is needed

  • system 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 addresses

    • the application chooses the destination address each time it uses the socket

      • e.g. when sending datagrams

    • or it can choose to bind the destination address to the socket and avoid necessity of repeatedly specifying address

      • e.g. a TCP connection

  • can also be used for traditional read - write operations

Socket API2: Application Layer


The socket api cont
The SOCKET API (cont)

  • sockets explicitly created, used, released by applications

  • based on client/server paradigm

  • two types of transport service via socket API:

    • unreliable datagram

    • reliable, stream-oriented

  • presentation, session layers missing in UNIX networking (an application concern!).

Socket API2: Application Layer


Sockets conceptual view
Sockets: conceptual view

  • each socket has separate send/receive buffers, port id, parameters (application queryable and setable).

  • socket operations implemented as system calls into OS

  • user/kernel boundary crossed: overhead

Socket API2: Application Layer


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 desired

protocol Optional protocol id (usually 0)

possible family values

AF_UNIX local host domain

AF_INET internet domain

possible service type values

SOCK_STREAM virtual circuit socket

SOCK_DGRAM datagram socket

SOCK_RAW access to internal network

returns: channel number on success, or -1

Socket API2: Application Layer


Create a pair of connected UNIX domain sockets

#include <sys/socket.h>

int socketpair (af, type, protocol, sv)

int d;

int type;

int protocol;

int sv[2];

where:

af Address family (domain)of the socket, AF_UNIX

type Type of service, SOCK_STREAM/ SOCK_DGRAM

protocol Protocol of interest, 0 for default

sv Buffer in which to return descriptors

Description

The socket pair call is used in the UNIX domain only to create a connected pair of sockets in the style of the pipe() call.

A creator would typically fork() a child (or children) and use the channel inheritance of the offspring for full duplex IPC.

Unlike a pipe, both channel descriptors are open for reading and writing with no possible crosstalk.

returns: 0 on success, or -1

Socket API2: Application Layer


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 connect

name Name of peer or listening socket through which the connection will be made namelen Length of name (bytes)

possible name address formats

struct sockaddr_un{

short sun_family; /* AF_UNIX */

char sun_path[109]; /* UNIX file path */ };

struct 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

Socket API2: Application Layer


Sockets conceptual view1
Sockets: conceptual view

Socket API2: Application Layer


Socket API2: Application Layer


Connectionless service
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, need to declare :

    • port number at which you are waiting for other side to send data

Socket API2: Application Layer


Socket API2: Application Layer


Creating a socket
Creating a socket

  • Socket system call creates sockets on demand

  • Takes 3 integer arguments and returns an integer result :

    • result = socket ( pf, type, protocol )

    • pf argument- specifies the protocol family to be used with the socket

      • i.e how to interpret addresses when supplied

    • type argument specifies the type of communication desired

    • protocol argument allows further flexibility

Socket API2: Application Layer


Creating a socket1
Creating a socket

  • same endpoint (socket) 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:

Socket API2: Application Layer


Creating a socket cont
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


Internet addressing
Internet Addressing

  • each Internet host has one or more globally-unique 32-bit IP addresses

  • host may have two or more addresses

    • address associated with each interface card

  • dotted decimal notation:

    • 4 decimal integers, each specifying one byte of IP address: host name cs.uml.edu

    • 32-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


The internet domain system structure
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

Socket API2: Application Layer


Dns internet domain name system
DNS: Internet Domain Name System

  • a distributed database used by TCP/IP applications to map to/from hostnames from/to IP addresses

  • name servers :

    • user-level library routines gethostbyname() and gethostbyaddress() contact the local nameserver via port 53

    • name server returns IP address of requested hostname

Socket API2: Application Layer


Dns non local names
DNS: non-local names

finding non-local names

  • no single name server has complete information table

  • if local name server can't resolve address, contacts root name server:

    • 9 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 servers

Socket API2: Application Layer


Assigning a socket a network address bind
Assigning a socket a network address: bind()

  • each socket must be associated with a

    • local,

    • host-unique

    • 16-bit port number.

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

  • 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

Socket API2: Application Layer


Socket addressing predefined address structures
Socket addressing: predefined address structures

specifying 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 */ };

Socket API2: Application Layer


The bind system call
The bind() system call

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

  • sockfdis the variable assigned socket() return value.

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

  • addresslenis the size of the address structure

    error return indicates port number already in use, out- of-range

Socket API2: Application Layer


The bind system call cont
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); /* > 5000

myaddr.sin_addr.s_addr = htonl(INADDR_ANY);

/* INADDR lets OS determine hostid */

if ( bind(sockfd, (struct sockaddr *) &myaddr, sizeof(myaddr)) < 0)

{ /* handle error */ }

Socket API2: Application Layer


Socket bind cont
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 bind

name Name to bind to socket

namelen Length of name (bytes)

Description

This 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 -1

Socket API2: Application Layer


Listen for connections on a socket

int 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 -1

SYNOPSIS

#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 requests

addr Structure to receive the address of connected peer

addrlen On input contains the number of bytes available for the peer address; updated to indicate the number of bytes returned

returns: Connected new channel number, or -1

Socket API2: Application Layer


Example With Internet Sockets

Client/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


Client server example using internet sockets
Client/Server example using internet sockets

A "one-time" FTP client

main(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


Client/Server example using internet sockets cont'd

A "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


Client/Server example using internet sockets cont'd

A "one-time" FTP client

while(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);

}

}

Socket API2: Application Layer


Example connectionless server
Example: connectionless server

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 <errno.h>

7 #define MY_PORT_ID 6090 /* a number > 5000 */

8

9 main()

10 {

11 int sockid, nread, addrlen;

12 struct sockaddr_in my_addr, client_addr;

13 char msg[50];

14

Socket API2: Application Layer


Connectionless server cont
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);

Socket API2: Application Layer


Example connectionless server cont
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


Example connectionless client
Example: connectionless client

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 <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


connectionless client,cont.1

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);}

20

21 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

Socket API2: Application Layer


Connectionless client 2
connectionless client , 2

30 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


Example execution trace
Example: execution trace

> cc udpserver.c; mv a.out udpserver

> cc udpclient.c; mv a.out udpclient

> udpserver &

[1] 20837

> Server: creating socket

Server: binding my local socket

Server: starting blocking message read

> udpclient

Client: creating socket

Client: binding my local socket

Client: creating addr structure for server

Client: initializing message and sending

Server: return code from read is 11

Server: message is: Hello world

[1] Done udpserver

Socket API2: Application Layer


Connection oriented service

Connection-oriented service

Socket API2: Application Layer


SERVER

CLIENT

create transport

endpoint:socket()

for incoming requests

create transport

endpoint: socket()

assign trasnport

endpoint an address

(optional) :bind()

assign address

to transport endpoint:bind()

announce willing to

accept connections: listen()

determine addr. of server

msg exchange

and synch.

connect to server

via socket: connect()

block/wait for

incoming conn. req.:

accept()(new socket

created on return)

request

send msg: sendto()

wait for pkt:recvfrom()

reply

wait for reply:recvfrom()

send reply (if any):sendto()

release transport

endpoint:close()

release transport

endpoint:close()

Socket API2: Application Layer


Connection oriented service1
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


Client to server connection connect
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


Client to server connection connect1
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_in structure holding server address info. Must be cast to type sockaddr.

  • addresslen is the size of address structure

Socket API2: Application Layer


The listen system call
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 anaccept().Typical value is 5.

Socket API2: Application Layer


Server to client connection accept
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


Accept cont
accept(), cont

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

  • sockfd is variable assigned socket() return value.

  • *fromaddrptr is address of sockaddr_in structure 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


Accept cont1
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


A simple timing application
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


A simple timing application client code
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


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 }

20

21 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


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


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


A simple timing application server code
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


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


33 for (i=1; i<=50000 ;i++) {34 /* accept a connection */35 newsockid = accept(sockid, (struct sockaddr *)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


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


Typical server structure
Typical server structure

Socket API2: Application Layer


Server structure code fragment
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


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


Sending and receiving data
Sending and Receiving Data

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

Socket API2: Application Layer


Sendto
sendto()

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

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

  • *buff is a set of consecutive mem. locs. holding message to send

  • bufflen is number of bytes to send

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

  • *toaddrptr is address of sockaddr_in structure holding destination address info. Must be cast to type sockaddr.

  • addresslen is the size of the address structure

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

Socket API2: Application Layer


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,and put 23 bytes of data into buffer */retcode = sendto(sockfd, buffer, 23, 0, (struct sockaddr *) &other_app_addr,sizeof(other_app_addr))

Example: using sendto()

Socket API2: Application Layer


Recvfrom

int recvfrom (int sockfd, char *buff, int bufflen, int flags, struct sockaddr *fromaddrptr, int *addresslen)

sockfd is variable assigned socket() return value.

*buff is a set of consecutive mem. locs. into which received data to be written

bufflen is number of bytes to read

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

*fromaddrptr is address of sockaddr_in structure containing address info of socket that sent this data. A returned value.

addresslen is size of address structure. A returned value.

recvfrom() returns number bytes actually received

recvfrom()

Socket API2: Application Layer


Example using recvfrom
Example: using recvfrom() flags, struct sockaddr *fromaddrptr, int *addresslen)

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


Scatter read and gather write
Scatter read and gather write flags, struct sockaddr *fromaddrptr, int *addresslen)

used to read/write into/from multiple non-contiguous buffers

writev(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


Socket API flags, struct sockaddr *fromaddrptr, int *addresslen)2: Application Layer


Byte ordering routines
Byte Ordering Routines flags, struct sockaddr *fromaddrptr, int *addresslen)

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

  • different computers may store bytes of 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).

Socket API2: Application Layer


Big endian little endian
Big Endian/Little Endian flags, struct sockaddr *fromaddrptr, int *addresslen)

Socket API2: Application Layer


Unix procedures
UNIX Procedures flags, struct sockaddr *fromaddrptr, int *addresslen)

Socket API2: Application Layer


Aside other useful system calls and routines
Aside: other useful system calls and routines flags, struct sockaddr *fromaddrptr, int *addresslen)

  • close(sockfd)will release a socket

  • getsockopt()andsetsockopt()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


Asynchronous i o
Asynchronous I/O flags, struct sockaddr *fromaddrptr, int *addresslen)

  • 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


Asynchronous i o example
Asynchronous I/O: example flags, struct sockaddr *fromaddrptr, int *addresslen)

#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


while (1==1) { flags, struct sockaddr *fromaddrptr, int *addresslen) ..…

/ * 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


The select system call
The select() system call flags, struct sockaddr *fromaddrptr, int *addresslen)

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

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

  • I/O multiplexing using select():

    • inform OS of set of sockets we're interested in

    • call select(), which won't return until I/O pending on one of specified sockets

    • select() will tell us which sockets are ready for I/O

    • do I/O (e.g., accept(), recvmsg()) on appropriate socket

Socket API2: Application Layer


The select system call1
The select() system call flags, struct sockaddr *fromaddrptr, int *addresslen)

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

    int select(int maxsockets, fd_set *readytoread, fd_set *readytowrite, fd_set *readyexceptions, struct timeval *timeptr);

Socket API2: Application Layer


The select system call simple example
The select() system call: simple example flags, struct sockaddr *fromaddrptr, int *addresslen)

#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


The select system call simple example1
The select() system call: simple example flags, struct sockaddr *fromaddrptr, int *addresslen)

/* 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


ad