1 / 86

Lecture 12 Overview

Lecture 12 Overview. UDP Connected mode. A UDP socket can be used in a call to connect() This simply tells the O.S. the address of the peer No handshake is made to establish that the peer exists No data of any kind is sent on the network as a result of calling connect() on a UDP socket.

talor
Download Presentation

Lecture 12 Overview

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lecture 12 Overview

  2. UDP Connected mode • A UDP socket can be used in a call to connect() • This simply tells the O.S. the address of the peer • No handshake is made to establish that the peer exists • No data of any kind is sent on the network as a result of calling connect() on a UDP socket CPE 401/601 Lecture 12 : Socket Programming Issues

  3. Connected UDP • Once a UDP socket is connected: • can use sendto() with a null dest address • can use write() and send() • can use read() and recv() • only datagrams from the peer will be returned • Asynchronous errors will be returned to the process OS Specific, some won’t do this! CPE 401/601 Lecture 12 : Socket Programming Issues

  4. Asynchronous Errors • What happens if a client sends data to a server that is not running? • ICMP “port unreachable” error is generated by receiving host and sent to sending host • The ICMP error may reach the sending host after sendto() has already returned! • The next call dealing with the socket could return the error CPE 401/601 Lecture 12 : Socket Programming Issues

  5. I/O Multiplexing • We often need to be able to monitor multiple descriptors: • a generic TCP client (like telnet) • a server that handles both TCP and UDP • Client that can make multiple concurrent requests • browser CPE 401/601 Lecture 12 : I/O Multiplexing

  6. Example - generic TCP client • Input from standard input should be sent to a TCP socket • Input from a TCP socket should be sent to standard output • How do we know when to check for input from each source? STDIN TCP SOCKET STDOUT CPE 401/601 Lecture 12 : I/O Multiplexing

  7. Options • Use multiple processes/threads • Use nonblocking I/O • use fcntl() to set O_NONBLOCK • Use alarm and signal handler to interrupt slow system calls • Use functions that support checking of multiple input sources at the same time CPE 401/601 Lecture 12 : I/O Multiplexing

  8. Non blocking I/O • Tell kernel not to block a process if I/O requests can not be completed • use fcntl() to set O_NONBLOCK: int flags; flags = fcntl(sock,F_GETFL,0); fcntl(sock,F_SETFL,flags | O_NONBLOCK); • Now calls to read() (and other system calls) will return an error and set errno to EWOULDBLOCK CPE 401/601 Lecture 12 : I/O Multiplexing

  9. Non blocking I/O while (! done) { if ( (n=read(STDIN_FILENO,…)<0)) if (errno != EWOULDBLOCK) /* ERROR */ else write(tcpsock,…) if ( (n=read(tcpsock,…)<0)) if (errno != EWOULDBLOCK) /* ERROR */ else write(STDOUT_FILENO,…) } CPE 401/601 Lecture 12 : I/O Multiplexing

  10. The problem with nonblocking I/O • Using blocking I/O allows the OS to put your process to sleep when nothing is happening • Once input arrives, the OS will wake up your process and read() (or whatever) will return • With nonblocking I/O, the process will chew up all available processor time!!! CPE 401/601 Lecture 12 : I/O Multiplexing

  11. Using alarms signal(SIGALRM, sig_alrm); alarm(MAX_TIME); read(STDIN_FILENO,…); ... signal(SIGALRM, sig_alrm); alarm(MAX_TIME); read(tcpsock,…); ... A function you write CPE 401/601 Lecture 12 : I/O Multiplexing

  12. “Alarming” Issues • What will happen to the response time ? • What is the ‘right’ value for MAX_TIME? CPE 401/601 Lecture 12 : I/O Multiplexing

  13. Select() • The select() system call allows us to use blocking I/O on a set of descriptors • file, socket, … • We can ask select to notify us when data is available for reading on either STDIN or a socket CPE 401/601 Lecture 12 : I/O Multiplexing

  14. select() int select( int maxfd, fd_set *readset, fd_set *writeset, fd_set *excepset, const struct timeval *timeout); • maxfd: highest number assigned to a descriptor • readset: set of descriptors we want to read from • writeset: set of descriptors we want to write to • excepset: set of descriptors to watch for exceptions • timeout: maximum time select should wait CPE 401/601 Lecture 12 : I/O Multiplexing

  15. Using select() • Create fd_set • Clear the whole thing with FD_ZERO • Add each descriptor you want to watch using FD_SET • Call select • when select returns, use FD_ISSET to see if I/O is possible on each descriptor CPE 401/601 Lecture 12 : I/O Multiplexing

  16. System Calls and Errors • In general, systems calls return a negative number to indicate an error • We often want to find out what error • Servers generally add this information to a log • Clients generally provide some information to the user CPE 401/601 Lecture 12 : Error Handling

  17. What is fatal? • How do you know what should be a fatal error? • Common sense • If the program can continue – it should • if a server can't create a socket, or can't bind to it's port • there is no sense continuing… CPE 401/601 Lecture 12 : Error Handling

  18. extern int errno; • Whenever an error occurs, system calls set the value of the global variable errno • You can check errno for specific errors • errno is valid only after a system call has returned an error • System calls don't clear errno on success • If you make another system call you may lose the previous value of errno • printf makes a call to write! CPE 401/601 Lecture 12 : Error Handling

  19. General Strategies • Include code to check for errors after every system call • Develop "wrapper functions" that do the checking for you • Develop layers of functions, each hides some of the error-handling details CPE 401/601 Lecture 12 : Error Handling

  20. Wrappers are great! • Wrappers like those used in the text can make code much more readable • There are always situations in which you cannot use the wrappers • Sometimes system calls are "interrupted" (EINTR) • this is not always a fatal error ! CPE 401/601 Lecture 12 : Error Handling

  21. Another approach • Instead of simple wrapper functions, you might develop a layered system • The idea is to "hide" the sockaddr and error handling details behind a few custom functions: • int tcp_client(char *server, int port); • int tcp_server(int port); CPE 401/601 Lecture 12 : Error Handling

  22. Layers and Code Re-use • Developing general functions that might be re-used in other programs is obviously "a good thing" • Layering is beneficial even if the code is not intended to be re-used: • hide error-handling from "high-level" code • hide other details • often makes debugging easier CPE 401/601 Lecture 12 : Error Handling

  23. The Best Approach to handling errors • There is no best approach • Do what works for you • Make sure you check all system calls for errors! • Not checking can lead to security problems! • Not checking can lead to bad grades on assignments! CPE 401/601 Lecture 12 : Error Handling

  24. Lecture 13Client/Server Programming CPE 401 / 601 Computer Network Systems slides are modified from Dave Hollinger slides are modified from Dave Hollinger

  25. Issues in Client/Server Programming • Identifying the Server • Looking up an IP address • Looking up a well known port name • Specifying a local IP address • UDP/TCP client design CPE 401/601 Lecture 13 : Client/Server Issues

  26. Identifying the Server • Options: • hard-coded into the client program • require that the user identify the server • read from a configuration file • use a separate protocol/network service to lookup the identity of the server. CPE 401/601 Lecture 13 : Client/Server Issues

  27. Identifying a TCP/IP server • Need an IP address, protocol and port • We often use host names instead of IP addresses • usually the protocol is not specified by the user • UDP vs. TCP • often the port is not specified by the user CPE 401/601 Lecture 13 : Client/Server Issues

  28. Services and Ports • Many services are available via “well known” addresses (names) • There is a mapping of service names to port numbers: struct *servent getservbyname( char *service, char *protocol ); • servent->s_port is the port number in network byte order CPE 401/601 Lecture 13 : Client/Server Issues

  29. Specifying a Local Address • When a client creates and binds a socket, it must specify a local port and IP address • Typically clients don’t care what port it is on: haddr->port = htons(0); give me any available port ! CPE 401/601 Lecture 13 : Client/Server Issues

  30. Local IP address • A client can also ask the operating system to take care of specifying the local IP address: haddr->sin_addr.s_addr= htonl(INADDR_ANY); Give me the appropriate address CPE 401/601 Lecture 13 : Client/Server Issues

  31. UDP Client Design • Establish server address (IP and port) • Allocate a socket • Specify that any valid local port and IP address can be used • Communicate with server (send, recv) • Close the socket CPE 401/601 Lecture 13 : Client/Server Issues

  32. Connected mode UDP • A UDP client can call connect() to establish the address of the server • The UDP client can then use read() and write() or send() and recv() • A UDP client using a connected mode socket can only talk to one server • using the connected-mode socket CPE 401/601 Lecture 13 : Client/Server Issues

  33. TCP Client Design • Establish server address (IP and port) • Allocate a socket • Specify that any valid local port and IP address can be used • Call connect() • Communicate with server (read, write) • Close the connection CPE 401/601 Lecture 13 : Client/Server Issues

  34. Closing a TCP socket • Many TCP based application protocols support • multiple requests and/or • variable length requests over a single TCP connection • How does the server known when the client is done ? • and it is OK to close the socket ? CPE 401/601 Lecture 13 : Client/Server Issues

  35. Partial Close • One solution is for the client to shut down only it’s writing end of the socket • shutdown() system call provides this function shutdown(int s, int direction); • direction can be 0 to close the reading end or 1 to close the writing end • shutdown sends info to the other process! CPE 401/601 Lecture 13 : Client/Server Issues

  36. TCP sockets programming • Common problem areas: • null termination of strings • reads don’t correspond to writes • synchronization (including close()) • ambiguous protocol CPE 401/601 Lecture 13 : Client/Server Issues

  37. TCP Reads • Each call to read() on a TCP socket returns any available data • up to a maximum • TCP buffers data at both ends of the connection • You must be prepared to accept data 1 byte at a time from a TCP socket! CPE 401/601 Lecture 13 : Client/Server Issues

  38. Server Design Concurrent Large or variable size requests Harder to program Typically uses more system resources Iterative Small, fixed size requests Easy to program CPE 401/601 Lecture 13 : Client/Server Issues

  39. Server Design Connection-Oriented EASY TO PROGRAM transport protocol handles the tough stuff. requires separate socket for each connection. Connectionless less overhead no limitation on number of clients CPE 401/601 Lecture 13 : Client/Server Issues

  40. Server Design Iterative Connectionless Iterative Connection-Oriented Concurrent Connectionless Concurrent Connection-Oriented CPE 401/601 Lecture 13 : Client/Server Issues

  41. Statelessness • State: Information that a server maintains about the status of ongoing client interactions • Connectionless servers that keep state information must be designed carefully! Messages can be duplicated! CPE 401/601 Lecture 13 : Client/Server Issues

  42. The Dangers of Statefullness • Clients can go down at any time • Client hosts can reboot many times • The network can lose messages • The network can duplicate messages CPE 401/601 Lecture 13 : Client/Server Issues

  43. Concurrent Server Design Alternatives • One child per client • Spawn one thread per client • Preforking multiple processes • Prethreaded Server CPE 401/601 Lecture 13 : Client/Server Issues

  44. One child per client • Traditional Unix server: • TCP: after call to accept(), call fork() • UDP: after recvfrom(), call fork() • Each process needs only a few sockets • Small requests can be serviced in a small amount of time • Parent process needs to clean up after children!!!! • call wait() CPE 401/601 Lecture 13 : Client/Server Issues

  45. One thread per client • Almost like using fork • call pthread_create instead • Using threads makes it easier to have sibling processes share information • less overhead • Sharing information must be done carefully • use pthread_mutex CPE 401/601 Lecture 13 : Client/Server Issues

  46. Prefork()’d Server • Creating a new process for each client is expensive • We can create a bunch of processes, each of which can take care of a client • Each child process is an iterative server CPE 401/601 Lecture 13 : Client/Server Issues

  47. Prefork()’d TCP Server • Initial process creates socket and binds to well known address. • Process now calls fork() a bunch of times • All children call accept() • The next incoming connection will be handed to one child CPE 401/601 Lecture 13 : Client/Server Issues

  48. Preforking • Having too many preforked children can be bad • Using dynamic process allocation instead of a hard-coded number of children can avoid problems • Parent process just manages the children • doesn’t worry about clients CPE 401/601 Lecture 13 : Client/Server Issues

  49. Sockets library vs. system call • A preforked TCP server won’t always work if sockets is not part of the kernel • calling accept() is a library call, not an atomic operation • We can get around this by making sure only one child calls accept() at a time using some locking scheme CPE 401/601 Lecture 13 : Client/Server Issues

  50. Prethreaded Server • Same benefits as preforking • Can also have the main thread do all the calls to accept() • and hand off each client to an existing thread CPE 401/601 Lecture 13 : Client/Server Issues

More Related