1 / 35

Overview

Overview. Last Lecture Nonblocking I/O and ioctl operations Source: Chapter 16 & 17 of Stevens’ book This Lecture Advanced UDP sockets and threads Source: Chapters 22&26 of Stevens’ book Next Lecture Signal-driven I/O, Raw sockets Source: Chapters 25&28&29 of Stevens’ book. recvmsg.

byron
Télécharger la présentation

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. Overview • Last Lecture • Nonblocking I/O and ioctl operations • Source: Chapter 16 & 17 of Stevens’ book • This Lecture • Advanced UDP sockets and threads • Source: Chapters 22&26 of Stevens’ book • Next Lecture • Signal-driven I/O, Raw sockets • Source: Chapters 25&28&29 of Stevens’ book

  2. recvmsg • recvmsg • Prototype: recvmsg(int s, struct msghdr *msg, int flags) struct msghdr { void *msg_name; /* optional address */ socklen_t msg_namelen; /* size of address */ struct iovec *msg_iov; /* scatter/gather array */ size_t msg_iovlen; /* # elements in msg_iov */ void *msg_control; /* ancillary data, see below */ socklen_t msg_controllen; /*ancillary data buffer len */ int msg_flags; /* flags on received message */ };

  3. Protocol control data • Control data • struct cmsghdr { • socklen_t cmsg_len; /* data byte count, including hdr */ • int cmsg_level; /* originating protocol */ • int cmsg_type; /* protocol-specific type */ • /* followed by • u_char cmsg_data[]; */ • };

  4. Destination address and etc. • It is necessary to determine the destination address of a UDP datagram, the interface on which the datagram was received, and to get some receiving flags (refer to advio/recvfromflags.c and advio/dgechoaddr.c) • recvmsg should be used • msg_flags member of msghdr structure returns flags to the application • Use IP_RECVDSTADDR socket option to get the destination address of the received datagram from the msg_control member • Use the IP_RECVIF socket option to get the index of the interface on which the datagram was received from the msg_control member. • Unfortunately the above two options are not supported on Linux

  5. Datagram truncation • When a UDP datagram arrives that is larger than the application’s buffer, the recvmsg sets the MSG_TRUNC flag in the msg_flags member of the msghdr structure • There are three possible implementations regarding truncated datagrams • Discard the excess bytes and return the MSG_TRUNC flag to the application (BSD/OS, Linux) • Discard the excess bytes but do not tell the application (Solaris 2.5) • Keep the excess bytes and return them in subsequent read operations on the socket (SVR4) • Always allocate an application buffer 1 byte greater than the largest datagram the application should ever receive!

  6. UDP vs. TCP • Advantages of UDP • Support broadcasting and multicasting • No connection setup or teardown • UDP minimum transaction time: RTT+SPT • TCP minimum transaction time: 2*RTT+SPT • If there are multiple request-reply exchanges, the cost of connection management is amortized • Features of TCP not provided by UDP • Positive acknowledgments, retransmission of lost packets, duplicate detection, and sequencing of packets • Windowed flow control • Slow start and congestion avoidance

  7. When to use UDP? • Recommendations • UDP must be used for broadcast or multicast applications • UDP can be used for simple request-reply applications but error detection must then be built into the application • Exception: HTTP uses TCP • UDP should not be used for bulk data transfer (e.g., file transfer). The reason is that windowed flow control, congestion avoidance, and slow start must all be built into the application (reinvent the wheel!) • Exception: TFTP and NFS use UDP for bulk data transfer.

  8. Adding reliability • Two features must be added to a UDP request-reply application (the client) in order to make data transmission reliable • Timeout and retransmission to handle datagrams that are discarded • Sequence numbers so the client can verify that a reply is for the appropriate request • The above features are part of most UDP applications such as DNS, SNMP and RPC. • Handling timeout • RTO=RTT+4*RTTvar • If the transmission timer expires, an exponential backoff must be used for next RTO • How to calculate RTT and RTTvar?

  9. Calculation of RTT • Estimated RTT • delta=measuredRTT - srtt • srtt=srtt+g*delta • rttvar=rttvar+h*(|delta|-rttvar) • g is 1/8, and h is 1/4 • Retransmission ambiguity problem • When a request is retransmitted, the measured RTT may not be the true RTT • One solution is not to use RTT of retransmitted requests to estimate RTT • Another solution is to use time-stamp: the client prepends to each request a timestamp the server must echo. • Refer to rtt/dg_send_recv.c and lib/rtt.c

  10. Binding interface addresses • The function get_ifi_info can be used for UDP applications to monitor all interfaces on a host to know when a datagram arrives, on which interface it arrives • Multiple server processes are forked to bind each interface address • Refer to advio/udpserv03.c

  11. Concurrent UDP servers • If the processing of a request is too long, a child UDP server can be forked • If the application is “request-reply” type, the forked child simply processes the request and reply • If the application exchanges multiple datagrams, the child server needs to create a new socket bound to an ephemeral port and use that socket to exchange datagrams with the client

  12. Concurrent UDP servers (cont.)

  13. Concurrent UDP servers (cont.)

  14. Threads • Problems with fork • Expensive: each time a copy of the process is created • Interprocess communication is required to pass information between the parent and the child • What are Threads? • Called light-weight processes • All threads share the same global memory, which makes the sharing of information easy between threads

  15. Sharing between Threads 1 • All threads within a process share • share process instructions • most data • open files (desrciptors) • signal handlers • current working directory • user and group IDs

  16. Sharing between Threads 2 • Each thread has its own • thread ID • set of registers (including program counter and stack pointer) • stack (for local variables and return addresses) • errno • signal mask • priority

  17. Posix thread functions 1 • pthread_create function int pthread_create (pthread_t *tid, const pthread_attr_t *attr, void *(*func)(void *), void *arg) • tid is the new thread’s ID • attr means attributes: priority, initial stack size, daemon thread or not. • The thread runs the function, func, with one argument, arg • Return value: 0 if OK, positive Exxx value on error

  18. Posix thread functions 2 • pthread_join function int pthread_join(pthread_t tid, void **status) • tid is the thread we want to wait for. • If status is not null, the return value from the thread is stored in the location pointed to by status • Return value: 0 if OK, positive Exxx value on error

  19. Posix thread functions 3 • pthread_self function pthread_t pthread_self(void) • Returns: thread ID of calling thread

  20. Posix thread functions 4 • pthread_detach function int pthread_detach(pthread_t tid) • Detach a thread. A detached thread, like a daemon, is not joinable and its resources are released when terminated • Returns: 0 if OK, positive Exxx value on error • If a thread wants to detach itself: pthread_detach(pthread_self());

  21. Posix thread functions 5 • pthread_exit function void pthread_exit(void *status) • One way for a thread to terminate is to call pthread_exit • status must not point to an object that is local to the calling thread. • Two other ways for a thread to terminate: • The function that started the thread calls return • If the main function of the process returns or if any thread calls exit, the process terminates, including any threads.

  22. str_cli Using Threads

  23. Thread-safe Functions

  24. Other Considerations • Passing arguments to new threads • Don’t share arguments, e.g. connfd in threads/tcpserv01.c • Thread-safe functions • Can be called by multiple threads concurrently without data race condition • Posix.1 requires that all functions be thread-safe, with some exceptions in Figure 23.5

  25. Thread-Specific Data • Common problem is due to static variables • Solutions to convert a function to be thread-safe • Use thread-specific data • Caller packages all static variables into a structure and to use this structure as an argument to the function • Restructure the interface to avoid any static variables

  26. Thread-specific data 1

  27. Thread-specific data 2

  28. Thread-specific data 3

  29. Thread-specific data 4

  30. Thread Termination • The call to pthread_key_create has an argument for a destructor function • When a thread terminates, the system will call the destructor function • It should free allocated memory.

  31. Mutual Exclusion 1 • Sometimes threads must share global data • Leads to race conditions

  32. Mutual Exclusion 2 int pthread_mutex_lock(pthread_mutex_t *mptr) int pthread_mutex_unlock(pthread_mutex_t *mptr)

  33. Condition Variables 1 • Sometimes we need to go to sleep until some condition occurs • Do not want to use busy waiting • A condition variable with a mutex • Mutex provides mutual exclusion • Condition varialbe provides a signaling mechanism

  34. Condition Variables 2 int pthread_cond_wait( pthread_cond_t *cptr, pthread_mutex_t *mptr) int pthread_cond_signal( pthread_cond_t *cptr) • All return: 0 if OK, positive Exxx value on error • Example

  35. Condition Variables 3 int pthread_cond_broadcast( pthread_cond_t *cptr) int pthread_cond_timewait( pthread_cond_t *cptr, pthread_mutex_t *mptr, const structtimespec *abstime) • All return: 0 if OK, positive Exxx value on error

More Related