Review: TCP Client-Server InteractionBerkeley SocketsMultiple Simultaneous Connections?Socket I/O: select()Slide 5Slide 6UDP Server ExampleSocket I/O: socket()Socket I/O: bind()UDP Client ExampleSlide 11Socket I/O: sendto()Socket I/O: recvfrom()Socket I/O: recvfrom() continued...Review: UDP Client-Server InteractionFamiliar Problem?Slide 17Slide 1801/14/191Review: TCP Client-Server Review: TCP Client-Server InteractionInteractionsocket()bind()listen()accept()write()read()read()TCP Serverclose()socket()TCP Clientconnect()write()read()close()connection establishmentdata requestdata replyend-of-file notificationfrom UNIX Network Programming Volume 1, figure 4.101/14/192Berkeley SocketsBerkeley SocketsBased on a presentation originally by Josh Brock circa 1999.01/14/193TCPIPEthernet AdapterWeb ServerMultiple Simultaneous Multiple Simultaneous Connections?Connections?Port 80How can a a web server managemultiple connections simultaneously?Port 800101/14/194Socket I/O: select()Socket I/O: select()int select(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);FD_CLR(int fd, fd_set *fds); /* clear the bit for fd in fds */FD_ISSET(int fd, fd_set *fds); /* is the bit for fd in fds? */FD_SET(int fd, fd_set *fds); /* turn on the bit for fd in fds */FD_ZERO(fd_set *fds); /* clear all bits in fds */maxfds : number of descriptors to be tested–descriptors (0, 1, ... maxfds-1) will be testedreadfds: a set of fds we want to check if data is available–returns a set of fds ready to read–if input argument is NULL, not interested in that conditionwritefds: returns a set of fds ready to writeexceptfds: returns a set of fds with exception conditions01/14/195Socket I/O: select()Socket I/O: select()int select(int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);struct timeval {long tv_sec; /* seconds /long tv_usec; /* microseconds */}timeout–if NULL, wait forever and return only when one of the descriptors is ready for I/O–otherwise, wait up to a fixed amount of time specified by timeoutif we don’t want to wait at all, create a timeout structure with timer value equal to 0Refer to the man page for more information01/14/196int fd, next=0; /* original socket */int newfd[10]; /* new socket descriptors */while(1) {fd_set readfds;FD_ZERO(&readfds); FD_SET(fd, &readfds);/* Now use FD_SET to initialize other newfd’s that have already been returned by accept() */select(maxfd+1, &readfds, 0, 0, 0);if(FD_ISSET(fd, &readfds)) {newfd[next++] = accept(fd, ...); }/* do the following for each descriptor newfd[n] */if(FD_ISSET(newfd[n], &readfds)) {read(newfd[n], buf, sizeof(buf));/* process data */}}Socket I/O: select()Socket I/O: select()Now the TCP server can support multiple connections...01/14/197UDPIPEthernet AdapterNTPdaemonUDP Server ExampleUDP Server ExamplePort 123For example: NTP daemonWhat does a UDP server need to do so that a UDP client can connect to it?01/14/198Socket I/O: socket()Socket I/O: socket()The UDP server must create a datagram socket…int fd; /* socket descriptor */if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror(“socket”);exit(1);}socket returns an integer (socket descriptor)–fd < 0 indicates that an error occurredAF_INET: associates a socket with the Internet protocol familySOCK_DGRAM: selects the UDP protocol01/14/199Socket I/O: bind()Socket I/O: bind()A socket can be bound to a portint fd; /* socket descriptor */struct sockaddr_in srv; /* used by bind() *//* create the socket *//* bind: use the Internet address family */srv.sin_family = AF_INET;/* bind: socket ‘fd’ to port 80*/srv.sin_port = htons(80);/* bind: a client may connect to any of my addresses */srv.sin_addr.s_addr = htonl(INADDR_ANY);if(bind(fd, (struct sockaddr*) &srv, sizeof(srv)) < 0) {perror("bind"); exit(1);}Now the UDP server is ready to accept datagrams…01/14/1910UDPIPEthernet Adapter2 UDP ClientsUDP Client ExampleUDP Client ExampleportsHow does a UDP client communicatewith a UDP server?01/14/1911Socket I/O: socket()Socket I/O: socket()This should be familiar – this time no bind()!int fd; /* socket descriptor */if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {perror(“socket”);exit(1);}socket returns an integer (socket descriptor)–fd < 0 indicates that an error occurredAF_INET: associates a socket with the Internet protocol familySOCK_DGRAM: selects the UDP protocol01/14/1912Socket I/O: sendto()Socket I/O: sendto()write is not allowed to a UDP socket – it is message based.–a port number is dynamically assigned when the first sendto is calledint fd; /* socket descriptor */struct sockaddr_in srv; /* used by sendto() *//* 1) create the socket *//* sendto: send data to IP Address “128.2.35.50” port 80 */srv.sin_family = AF_INET;srv.sin_port = htons(80); srv.sin_addr.s_addr = inet_addr(“128.2.35.50”);nbytes = sendto(fd, buf, sizeof(buf), 0 /* flags */, (struct sockaddr*) &srv, sizeof(srv));if(nbytes < 0) {perror(“sendto”); exit(1);}01/14/1913Socket I/O: recvfrom()Socket I/O: recvfrom()int fd; /* socket descriptor */struct sockaddr_in srv; /* used by bind() */struct sockaddr_in cli; /* used by recvfrom() */char buf[512]; /* used by recvfrom() */int cli_len = sizeof(cli); /* used by recvfrom() */int nbytes; /* used by recvfrom() *//* 1) create the socket *//* 2) bind to the socket */nbytes = recvfrom(fd, buf, sizeof(buf), 0 /* flags */, (struct sockaddr*) &cli, &cli_len);if(nbytes < 0) {perror(“recvfrom”); exit(1);}01/14/1914Socket I/O: recvfrom() Socket I/O: recvfrom() continued...continued...nbytes = recvfrom(fd, buf, sizeof(buf), 0 /* flags */, (struct sockaddr*) cli, &cli_len);The actions performed by recvfrom–returns the number of bytes read (nbytes)–copies nbytes of data into buf–returns the address of the client (cli)–returns the length of cli (cli_len)–don’t worry about flags receive out-of-band data, peek, wait for full request01/14/1915Review: UDP Client-Server Review: UDP Client-Server InteractionInteractionsocket()bind()recvfrom()sendto()UDP Serversocket()UDP Clientsendto()recvfrom()close()blocks until datagramreceived from a clientdata requestdata replyfrom UNIX Network Programming Volume 1, figure 8.101/14/1916int s1; /* socket descriptor 1 */int s2; /* socket descriptor 2 *//* 1) create socket s1 *//* 2) create socket s2 *//* 3) bind s1 to port 2000 *//* 4) bind
View Full Document