Presentation is loading. Please wait.

Presentation is loading. Please wait.

Network Application Programming Introduction: issues Sockets: programming and implementation Other API’s:  winsock  java  transport layer interface.

Similar presentations


Presentation on theme: "Network Application Programming Introduction: issues Sockets: programming and implementation Other API’s:  winsock  java  transport layer interface."— Presentation transcript:

1 Network Application Programming Introduction: issues Sockets: programming and implementation Other API’s:  winsock  java  transport layer interface (TLI)  Novell netware API Reading:  textbook, page 486-487  ftp://gaia.cs.umass.edu/cs653/sock.ps Copyright 1998. All Rights Reserved, J. Kurose, D. Towsley

2 The Application Programming Interface: API  API: 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?

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

4 The SOCKET API  introduced in 1981 BSD 4.1 UNIX  a host-local, application created/owned, OS- controlled interface into which 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.

5 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!).

6 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

7 Sockets: conceptual view

8 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 waiting for other side

9

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

11 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 #include int sockfd; if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { /* handle error */ }

12 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:  library procedure inet_addr() converts dotted- decimal address string to a 32-bit address  library procedure gethostbyname() converts textual name to dotted-decimal.

13 The Internet Domain System Structure  hierarchical administering of names  e.g.: gaia.cs.umass.edu  leftmost name is typically a host name (has an IP address)  next leftmost name is organization administering that host (e.g., UMass CS Dept.)  next leftmost name is organization administering all of subnames to the left (e.g., UMass administers cs, ecs, ucs domains)  rightmost (highest) domain an organization, structure, country

14 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 local nameserver via port 53  name server returns IP address of requested hostname

15 DNS: non-local names finding non-local names  no single name server has complete info  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., umass.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

16 Assigning 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 to be delivered (demultiplexed to) to this socket  a return address for outgoing messages

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

18 The bind() system call int bind ( int sockfd, struct sockaddr *myaddr, int addresslen) is the variable assigned socket() return value.  sockfd is the variable assigned socket() return value. address ofsockaddr_in structure holding local address info. Must be cast to type sockaddr.  *myaddr: address of sockaddr_in structure holding local address info. Must be cast to type sockaddr. is the size of the address structure  addresslen is the size of the address structure error return indicates port number already in use, out-of-range

19 The bind() system call (cont) #include #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 */ }

20 Example: connectionless server 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 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

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

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

23 Example: connectionless client 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 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 {

24 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); 20 exit(0); 21 } 22 23 printf("Client: binding my local socket\n"); 24 bzero((char *) &my_addr, sizeof(my_addr)); 25 my_addr.sin_family = AF_INET; 26 my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 27 my_addr.sin_port = htons(MY_PORT_ID); 28 if ( ( bind(sockid, (struct sockaddr *) &my_addr, 29 sizeof(my_addr)) < 0) ){ 30 printf("Client: bind fail: %d\n",errno); 31 exit(0); 32 } 33

25 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); 42 exit(0); 43 } 42 43 /* close socket */ 44 close(sockid); 45 }

26 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

27 Connection-oriented service

28 SERVER assign address to transport endpointbind() to transport endpoint:bind() CLIENT create transport endpoint: socket() assign trasnport endpoint an address (optional) :bind() announce willing to accept 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 transport endpoint:close() send msg: sendto() wait for reply:recvfrom() create transport endpoint:socket() for incoming requests release transport endpoint:close() determine addr. of server msg exchange and synch. request reply

29 Connection-oriented service  client/server handshaking:  client must explicitly connect to server before sending or receiving data  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, stream-oriented.

30 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

31 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

32 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) variable assigned socket() return value. Process accepts incoming connections on this socket id.  sockfd: variable assigned socket() return value. Process accepts incoming connections on this socket id. maximum number of connection requests that can be queued, waiting for server to do anTypical value is 5.  maxwaiting: maximum number of connection requests that can be queued, waiting for server to do an accept(). Typical value is 5.

33 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  creates other (new) sockets for communication with clients  server can not selectively accept() connection requests  typically handled FCFS.

34 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.  addresslen is size of address structure. A value-result argument (set before call, reset during call).

35 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); &other_app_addr, &addrsize); /* newsockid to communicate with client, /* newsockid to communicate with client, sockid to accept more connections */ sockid to accept more connections */

36 A Simple Timing Application: 1 Client:  connect to server  send server client local time  read back server's local time Server:  receive connections from clients  print out client's local time  send client server's local time

37 A Simple Timing Application: client code 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 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

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

39 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

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

41 A Simple Timing Application: server code 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8 #define MY_PORT_ID 6090 /* a number > 5000 */ 9 10 main() 11 { 12 int sockid, newsockid, i,j; 13 struct sockaddr_in ssock_addr; 14 struct timeval tp; 15 struct timezone tzp; 16

42 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

43 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

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

45 Typical server structure

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

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

48 Sending and Receiving Data data sent/received using standard UNIX i/o system calls or network-specific system calls

49 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

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

51 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

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

53 Scatter read and gather write 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 */ };

54

55 Byte Ordering Routines 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).

56 Big Endian/Little Endian

57 UNIX Procedures

58 Aside: other useful system calls and routines will release a socket  close(sockfd) will release a socket andsystem calls used to query/set socket options.  getsockopt() and setsockopt() system calls used to query/set socket options. system call used to query/set socket attributes, also network device interface attributes.  ioctl() system call used to query/set socket attributes, also network device interface attributes.

59 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

60 Asynchronous I/O: example #include 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 */

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

62 The select() system call  application may want to respond to incoming i/o (e.g., data, connect requests) occurring on several different socket  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

63 The select() system call  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);

64 The select() system call: simple example #include 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);

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


Download ppt "Network Application Programming Introduction: issues Sockets: programming and implementation Other API’s:  winsock  java  transport layer interface."

Similar presentations


Ads by Google