Chapter 8: I/O functions & socket options 8.1 Introduction I/O Models In general, there are normally two phases for an input operation: 1) Waiting for the data to arrive on the network. When the packet arrives, copy it into a buffer within the kernel. 2) Copy this data from the kernel s buffer into the application buffer. Under UNIX, there are five available I/O models: Blocking I/O (blocking). Nonblocking I/O (polling). I/O Multiplexing (select and poll). Signal driven I/O (SIGIO). Asynchronous I/O (Posix.1). 8.1.1 Synchronous I/O versus Asynchronous I/O.1 definitions: A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes. An asynchronous I/O operation does not cause the requesting process to be blocked. Four I/O models belong to this category: Blocking. Non blocking. I/O multiplexing. Signal-driven I/O. 8.1.2 Blocking I/O Model: The most prevalent model; by default, all sockets are blocking. Blocking occurs under the following circumstances: Read: When no data has arrived yet; example a block in read() or recvfrom(). Write: When the internal buffers are full and waiting for transmission, the program requests for more data to be sent. Connection: When accept() and connect()find no pending connection in the listening queue. An application calls recvfrom. The system call does not return until the datagram arrives and is copied into application buffer, or an error occurs. The application is blocked the entire time from when it calls recvfrom until it returns. When recvfrom returns OK, the application processes the datagram. The most common error is the system call being interrupted by a signal. our process is blocked the entire time from when it calls recvfrom until it returns. When recvfrom returns successfully, our application processes the datagram. Fig 8.1 show Blocking I/O model.
8.1.3 Nonblocking I/O (polling). When an I/O operation requested by a process cannot be completed, the kernel does not put the process to sleep, but returns (immediately) an error. Can be used for a process that is monitoring more than one I/O. Use fcntl()system call to set O_NONBLOCK of the file descriptor. An application calls recvfrom. In nonblocking, the application sits in a loop calling recvfrom on a nonblocking descriptor (polling) & it can be a waste of CPU time. Fig 8.2 show Nonblocking I/O model
8.1.4 I/O Multiplexing (select and poll). An alternative to non blocking here the process is blocked until I/O is available from any of a set of file descriptors. We need the capability to tell the kernel that we want to be notified if one or more I/O conditions are ready. A client is handling two inputs at the same time: a standard input and a TCP Socket. The client is blocked in a call to fgets (on standard input). What happened when the server TCP process is killed? The server process correctly sends a FIN. But, the client never reads it because it is blocked in fgets. In I/O multiplexing, a call to select() or poll() is made and it blocks in one of these two systems calls, instead of blocking in the actual I/O system call. An application uses select() to wait for the datagram socket to be readable. The application is blocked in select() call, when the socket is not readable. select() returns when the socket is readable. Then, call recvfrom to copy the datagram into application buffer. Advantage: we can wait for more than one descriptor to be ready. Disadvantage: Similar to blocking I/O but requires two system calls. Fig 8.3 I/O multiplexing model
8.1.5 Signal driven I/O (SIGIO). The kernel will give notification with the SIGIO signal when the descriptor is ready so it is called signal driven I/O. Steps: Enable the socket for signal driven I/O. Install a signal handler using sigaction system call & return immediately, process is not blocked. When the datagram is ready to be read, the SIGIO signal is generated for the process. Process reads the datagram. The advantage of this model is that the process is not blocked while waiting for the datagram to arrive. The main loop can continue executing and just wait to be notified by the signal handler that either the data is ready to process or that the datagram is ready to be read. Fig 8.4 Signal-Driven I/O model