ipc 2 Flashcards

1
Q

What are Sockets?

A
  • Sockets are an extension of pipes, with the advantages that processes don’t need to be related, or even on the same machine
    – Method for accomplishing interprocess communication
    – Bidirectional communication
  • A socket is like the end point of a pipe – in fact, the Linux kernel implements pipes as a pair of sockets
  • Two (or more) sockets must be connected before they can be used to transfer data
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Socket Client-Server Model

A
  • IPC using sockets described as client-server model
    – One process is usually called the server
    – A server process is usually responsible for satisfying requests made by other processes called clients
    – A server usually has a well-known address (e.g., IP address or pathname)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Socket Attributes

A

Sockets are characterized by three attributes
– Domain
– Type
– Protocol

Socket Protocol
– Determined by socket type and domain
– Default protocol is 0

  • For communication between processes, sockets can be implemented in the following domains
    – UNIX (e.g., AF_UNIX)
  • Processes are on the same machine
    – INET (e.g., AF_INET)
  • Each process is on a different machine (i.e., requires a network interface device)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

types of sockets

A

Three main types of sockets:

– SOCK_STREAM (TCP sockets)
* Provides a connection-oriented, sequenced, reliable, and bidirectional network communication service
* E.g., telnet, ssh, HTTP

– SOCK_DGRAM (UDP sockets)
* Provides a connectionless, unreliable, best-effort network communication service
* E.g., streaming audio/video, IP telephony

– SOCK_RAW
* Allows direct access to other layer protocols such as IP, ICMP, or IGMP

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

UNIX Domain Sockets

A

include <sys/un.h>

  • Socket for communicating with another process on the same machine only
    – Provides an optimization since no network overhead
  • Uses sockaddr_un structure instead of sockaddr_in

struct sockaddr_un
{
sa_family_t sun_family; /* AF_UNIX /
char sun_path[108]; /
pathname */
};

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Stream Socket

A
  • Sequence of function calls for a client and server to implement a stream socket
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Steps in Server Process

A
  1. Call socket() with proper arguments to create the socket
  2. Call bind() to bind the socket to an address (in our case, it is just a pathname) in the UNIX domain
  3. Call listen() to instruct the socket to listen for incoming connections from client programs
  4. Call accept() to accept a connection from a client
  5. Handle the connection and loop back to accept()
  6. Close the connection
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Steps in Client Process

A
  1. Call socket() to get a UNIX domain socket to communicate through
  2. Set up a struct sockaddr_un with the remote address (where the server is listening) and call connect() with that as an argument
  3. Assuming no errors, you are connected to the remote side
    – Use send() and recv() to communicate
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Creating the Socket

A

include <sys/types.h>

#include <sys/socket.h>
int socket(int domain, int type, int protocol);

  • Creates an endpoint for communication (i.e., a socket) and returns a file descriptor
  • Common domains (or address family)
    – AF_UNIX Unix domain sockets
    – AF_INET IPv4 Internet sockets
    – AF_INET6 IPv6 Internet sockets
  • Type
    – SOCK_STREAM, SOCK_DGRAM, SOCK_RAW
  • Protocol
    – Set to 0 (chosen by OS) except for RAW sockets
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Bind to a Name (Server Side)

A

include <sys/types.h>

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *serveraddr, socklen_t addrlen);

  • Binds a name to the socket (i.e., reserves a port)
  • sockfd is the socket file descriptor returned by socket
  • serveraddr is the IP address and port of the machine (address usually set to INADDR_ANY – chooses a local address)
  • addrlen is the size (in bytes) of the structure
  • Returns 0 on success or –1 if an error occurs
  • When socket is bound, new special socket-type file (type “s”) corresponding to sun_path is created
  • This file is not automatically deleted, so need to unlink it
    – If bind finds the file already exists, it will fail
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

int listen (int sockfd, int backlog) (Server Side)

A

include <sys/types.h>

#include <sys/socket.h>
int listen(int sockfd, int backlog);

  • Listens for connections on a socket
    – After calling listen(), a socket is ready to accept connections
  • Prepares a queue in the kernel where partially completed connections wait to be accepted
  • Many client requests may arrive
    – Server cannot handle them all at the same time
    – Server could reject the requests or let them wait
    – backlog is the maximum number of partially completed connections that the kernel should queue
  • What if too many clients arrive?
    – Some requests don’t get through … makes no promises
    – And the client(s) can always try again!
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Establish Connection (Server Side)

A

include <sys/types.h>

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr* cliaddr, socklen_t * addrlen);

  • Accepts a connection on the socket and returns a new file descriptor that refers to the connection with the client that will be used for reads and writes on the connection
    – Blocks waiting for a connection (from the queue)
  • sockfd is the listening socket
  • cliaddr is the address of the client
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Establish Connection (Client Side)

A

include <sys/types.h>

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr* servaddr, socklen_t * addrlen);

  • Initiates a connection on the socket, where the kernel will select a source IP address and dynamic port
  • Returns 0 on success or –1 on failure
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Sending Data

A

include <sys/types.h>

#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

  • Alternative to write that sends a message on the socket
  • sockfd is socket descriptor for open and connected socket
  • buf is a buffer of information to send
  • len is the size of the buffer in bytes
  • flags
    – Bitwise OR of zero or more flags (e.g., MSG_EOR, MSG_OOB, etc.)
  • Calls are blocking (i.e., returns only after data is sent)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Receiving Data

A

include <sys/types.h>

#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

  • Alternative to read that receives a message on the socket
  • sockfd is socket descriptor for open and connected socket
  • buf is initially empty to store the data
  • len is the size of the buffer in bytes
  • flags
  • Bitwise OR of zero or more flags (e.g., MSG_EOR, MSG_OOB, etc.)
  • Calls are blocking (returns only after data is received)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Close and Shutdown

A

include <unistd.h></unistd.h>

int close(sockfd);
* Closes the file descriptor when done
* Will not deallocate the socket until we close the last descriptor that references it (we may have several)

int shutdown(int sockfd, int how);
* Forces a full or partial closure of a socket
* sockfd is a socket descriptor
* how can be SHUT_RD, SHUT_WR, or SHUT_RDWR

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Socket Pipe

A
  • What if you wanted a pipe(), but you wanted to use a single pipe to send and receive data from both sides?
    – Since most pipes are unidirectional (with exceptions in SYSTEM V), you cannot do it!
    – Unix System V is one of the first commercial versions of the Unix OS
  • UNIX domain sockets can handle bi-directional data
    – But, you would have to set up all that code with listen() and connect() with everything just to pass data both ways
  • However, you can use socketpair() that returns a pair of already connected sockets
    – No extra work needed and you can immediately use the socket descriptors for interprocess communication (only available in UNIX domain socket)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

socketpair() Function

A

include <sys/socket.h>

int socketpair(int family, int type, int protocol, int sockfd[2]);

  • Creates two unnamed sockets that are already connected
    (Unnamed: A stream socket that has not been bound to a pathname using bind(2) has no name)
  • They are full-duplex (i.e., data can go in each direction)
  • Also called stream pipes if type is SOCK_STREAM
  • Returns 0 on success, –1 on error
  • Family must be AF_LOCAL or AF_UNIX
  • Type is SOCK_DGRAM or SOCK_STREAM
  • Protocol must be 0
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

Layers of the IP Protocol Suite

A

application layer -> ftp
transport layer -> TCP, UDP
network layer -> IP
link layer -> ethernet

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Internet Sockets

A
  • Sockets provide a mechanism to communicate between computers across a network
  • Internet Sockets
    – AF_INET – the addresses are IPv4 addresses
    – AF_INET6 – the addresses are IPv6 addresses
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

What is the Internet?

A

Physical layer
Actual electrons on a wire

Datalink layer
Frames, MAC Addresses

Network layer
Router to router, Creates network IP addresses, Variable-length packets

Transport layer
Persistent communication channels, TCP, UDP, ports

Session layer
Open, close, manage sessions; AppleTalk, SCP

Presentation layer
String encoding,encryption /decryption
Object serialization, files, compression

Application layer
HTTP POST and GET requests

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

Byte Ordering of Integers

A
  • Different CPU architectures have different byte ordering. Byte ordering is an attribute of the processor, not the operating system running on it.
  • In computing, endianness is the order or sequence of bytes of a word of digital data in computer memory.
  • Endianness is expressed as big-endian or little-endian
  • Endianness may also be used to describe the order in which the bits are transmitted over a communication channel, e.g., big-endian in a communications channel transmits the most significant bits first
  • Little-Endian
    – Stores the least significant byte (LSB) in the smallest address
  • Big-Endian
    – Stores the most significant byte (MSB) in the smallest address
  • In order to connect to a remote computer and use a socket, we need to use its address
    – In fact, Linux is little-endian, but TCP/IP uses big-endian byte ordering
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

Byte Ordering

A
  • A byte (of 8 bits) has a limited range of 256 values. When a value is beyond this range, it has to be stored in multiple bytes.
  • A number such as 753 in hexadecimal format is 0x02F1. It requires at least two bytes of storage. The order in which these two bytes are stored in memory can be different. Byte 0x02 can be stored in lower memory address followed by 0xF1; or vice versa.
  • Programs must conform to the byte ordering as supported by the processor. If not, 0x02F1 might be wrongly interpreted as 0xF102, which is the number 61698 in decimal system. Byte ordering is also important when data is transferred across a
    network or between systems using different ordering.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Byte Ordering Problem

A

What would happen if two computers with different integer byte ordering communicate?
– Nothing… if they do not exchange integers!
– But… if they exchange integers, they would get the wrong order of bytes, and therefore, the wrong value!

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

Byte Ordering Solution

A
  • There are two solutions if computers (hosts) with different byte ordering systems want to communicate

– They must know the kind of architecture of the sending computer
* Bad solution, it has not been implemented

– Introduction of a network byte order. The functions are:
uint16_t htons(uint16_t host16bitvalue)
uint32_t htonl(uint32_t host32bitvalue)
uint16_t ntohs(uint16_t net16bitvalue)
uint32_t ntohl(uint32_t net32bitvalue)
* Use for all integers (short and long) that are sent across the network
– Including port numbers and IP addresses

26
Q

Network Byte Ordering Solution

A
  • A host system may be little-endian but when sending data into the network, it must convert data into big-endian format.
  • Likewise, a little-endian machine must first convert network data into little-endian before processing it.
  • Four common functions to do these conversions are (for 32-bit long and 16-bit, short) htonl, ntohl, htons and ntohs.
27
Q

Byte Ordering Solution

A
  • Network addresses in a given network must all follow a consistent addressing convention.
  • This convention, known as network byte order, defines the bit-order of network addresses as they pass through the network.
  • The TCP/IP standard network byte order is big-endian.
  • In order to participate in a TCP/IP network, little-endian systems usually bear the burden of conversion to network byte order.
28
Q

Naming and Addressing

A
  • Host name
    – Identifies a single host
    – Variable length string (e.g., www.unt.edu, cse01)
    – Is mapped to one or more IP addresses
  • IP Address (IPv4)
    – Written as dotted octets (e.g., 10.0.0.1)
    – 32 bits – not a number, but often needs to be converted to a 32-bit number to use
  • Port number
    – Identifies a process on a host
    – 16 bit number
29
Q

Addresses, Ports, and Sockets

A
  • Like apartments and mailboxes
    – You are the application
    – Street address of your apartment building is the IP address
    – Your mailbox is the port
    – The post-office is the network
    – The socket is the key that gives you access to the right mailbox
30
Q

Port Numbers

A

0-1023 are well known
1024-49151 are registered
49152-65535 are dynamic

31
Q

how to choose a port number

A
  • Choose a port number that is registered for general use, from 1024 to 49151
    – Do not use ports 0 to 1023. These ports are reserved (must be root) for use by the Internet Assigned Numbers Authority (IANA)
    – Avoid using ports 49152 through 65535. These are dynamic ports that operating systems use randomly
  • If you choose one of these ports, you risk a potential port conflict
32
Q

IP Address Data Structure

A

The sockaddr_in structure has four parts

struct sockaddr_in
{
short int sin_family; // address family
unsigned short int sin_port; // port number
struct in_addr sin_addr; // Internet address
unsigned char sin_zero[8]; // set to 0, padding
};

struct in_addr
{
unsigned long s_addr; // 4 bytes
};

33
Q

constructing the ip address data structure

A
  • Declare address structure
    struct sockaddr_in sockAdd;
  • Set family
    sockAdd.sin_family = AF_INET;
  • Set IP address (2 ways)
    // specify address to listen to
    // inet_pton - converts IPv4 and IPv6 addresses from text to binary form
    inet_pton(AF_INET, “127.0.0.1”, &sockAdd.sin_addr.s_addr)
    // listen to any local address
    sockAdd.sin_addr.s_addr = htonl(INADDR_ANY)
  • Set port
    sockAdd.sin_port = htons(9999);
34
Q

inet_addr()

A

include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>
in_addr_t inet_addr(const char* string)

  • Converts an IP address in IPv4 numbers-and-dots notation
    into binary form in network byte order
  • If string does not contain legitimate Internet address, returns
    value INADDR_NONE
35
Q

gethostname()

A

include <unistd.h></unistd.h>

int gethostname(char* name, int nameLen)

  • Gets the null-terminated hostname as a character array along with its length in bytes
36
Q

inet_aton()

A

include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp);

  • Converts an IP address in IPv4 numbers-and-dots notation into binary form in network byte order and stores it in an in_addr struct
37
Q

inet_ntoa()

A

include <sys/socket.h>

#include <netinet/in.h>
#include <arpa/inet.h>
char *inet_ntoa(struct in_addr in);

  • Converts an IP address in the in_addr struct in network byte order into a string in IPv4 dotted-decimal notation
38
Q

inet_ntop()

A

include <arpa/inet.h>

const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);

  • Converts a network address, either IPv4 or IPv6, from its binary to text form
39
Q

inet_pton()

A

include <arpa/inet.h>

int inet_pton(int af, const char *src, void *dst);

  • Converts a network address, either IPv4 or IPv6, from its text to binary form
40
Q

TCP

A

TCP
– Reliable byte stream service
– Different ways to build clients and servers
* Some problems when building clients/servers with TCP
– How to get around blocking I/O
– Data format conversion
* Basic assumption: whatever sent will eventually be received!!

41
Q

UDP

A

Unreliable datagram service
* Data may get lost – application may need to deal with more details in the communication

42
Q

Why UDP?

A
  • Applications that do not need 100% reliability communication
    – E.g., VoIP, video stream, DNS servers
  • Applications care a lot about performance
    – High performance computing (TCP cares too much about other things than performance)
  • Applications that need multicast or broadcast
    – TCP only supports point to point communication
43
Q

UDP Client/Server

A
  • Typical UDP client
  • Client does not establish a connection with the server
  • Client sends a datagram to the server using sendto function
  • Typical UDP server
  • Does not accept a connection from a client
  • Server calls recvfrom function that waits until data arrives from some client
44
Q

Datagram Socket

A

Sequence of function calls for a client and server to implement a datagram socket
– No “handshake”
– No simultaneous close

A datagram socket provides a symmetric data exchange interface without requiring connection establishment. Each message carries the destination address.

45
Q

Receiving a UDP Message

A

include<sys/socket.h>

ssize_t recvfrom(int sockfd, void *buff, size_t nbytes,
int flags,struct sockaddr *from, socklen_t *addrlen);

  • Receives a message on the socket
  • If recvfrom is successful, the number of bytes read is returned, -1 on error
46
Q

Sending a UDP Message

A

include <sys/socket.h>

ssize_t sendto(int sockfd, const void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t addrlen);

  • Sends a message on the socket
  • If sendto is successful, the number of bytes written, even if 0 bytes are written, is returned, -1 on error
47
Q

Blocking and Nonblocking IPC

A

Blocking refers to the process of how the program will wait for bytes to appear on the input stream
* When blocking is turned on, every function call for input will wait until data appears on the input stream. The program will not continue until input is received.
* When blocking is turned off, the function call will check to see if data is present. If data is present, read occurs normally, just as if blocking were turned on.
* However, if no data is present, the function call will return immediately and inform the program that no data is present. This allows the program to continue whether input data is present or not.

48
Q

Examples of Blocking and Nonblocking IPC

A

a. blocking interprocess communication
- disk data request
- network data transfer
- anything with a data dependency
b. nonblocking interprocess communication
- mode change

49
Q

The importance of being able to control blocking

A

For example: a banking machine typically does not wait forever for a user to enter a password, or to command a transaction. After waiting a fixed amount of time, a banking machine program typically continues to a portion of the program that ends the banking session, in order to protect the user. This is an example of timed blocking.

  • Consider a movie-playing program (E.g. VLC Media player, Windows Media Player etc).
  • A user expects to be able to rewind, pause, and interact with a film while it is playing back. This can be accomplished through nonblocking input.
50
Q

I/O Multiplexing

A

User is in charge of scheduling

51
Q

I/O Multiplexing defenition

A

I/O multiplexing is typically used in networking applications in the following scenarios:
* When a client is handling multiple descriptors (normally interactive input and a network socket)
* When a client to handle multiple sockets at the same time (this is possible, but rare)
* If a TCP server handles both a listening socket and its connected sockets
* If a server handles both TCP and UDP
* If a server handles multiple services and perhaps multiple protocols

I/O multiplexing is not limited to network programming. Many nontrivial
applications find a need for these techniques.

52
Q

phases of input operation

A
  • There are normally two distinct phases for an input operation:
  1. Waiting for the data to be ready. This involves waiting for data to arrive on the
    network. When the packet arrives, it is copied into a buffer within the kernel.
  2. Copying the data from the kernel to the process. This means copying the (ready) data from the kernel’s buffer into our application buffer
53
Q

Blocking I/O Model

A
  • The most prevalent model for I/O is the blocking I/O model.
  • By default, all sockets are blocking.

In the figure above, the process calls recvfrom and the system call does not return until the datagram arrives and is copied into our application buffer, or an error occurs

We say that the process is blocked the entire time from when it calls recvfrom until it returns. When recvfrom returns successfully, our application processes the datagram.

54
Q

Nonblocking I/O Model

A
  • When a socket is set to be nonblocking, we are telling the kernel “when an I/O operation that I request cannot be completed without putting the process to sleep, do not put the process to sleep, but return an error instead”.
  • For the first three recvfrom, there is no data to return and the kernel immediately returns an error of EWOULDBLOCK.
  • For the fourth time we call recvfrom, a datagram is ready, it is copied into our application buffer, and recvfrom returns successfully. We then process the data.
55
Q

Dealing with Blocking Calls

A
  • Many functions block
    – accept; until a connection comes in
    – connect; until the connection is established
    – recv, recvfrom; until a packet (of data) is received
    – send, sendto; until data is pushed into socket’s buffer
  • For simple programs, this is fine
  • What about complex connection routines?
    – Multiple connections
    – Simultaneous sends and receives
    – Simultaneously doing non-networking processing
  • Options
    – Create multi-process or multi-threaded code
    – Turn off blocking feature (e.g., use fcntl() file-descriptor control system call)
    – Use the select() function
  • What does select() do?
    – Can be permanent blocking, time-limited blocking, or non-blocking
    – Input is a set of file descriptors
    – Output is information on the file-descriptors’ status
    – Therefore, can identify sockets that are “ready for use” so that calls involving that socket will return immediately
56
Q

I/O Multiplexing Model

A

With I/O multiplexing, we call select or poll and block in one of these two system calls, instead of blocking in the actual I/O system call.
We block in a call to select, waiting for the datagram socket to be readable.
When select returns that the socket is readable, we then call recvfrom to copy the datagram into our application buffer.

57
Q

I/O Multiplexing Model Vs Blocking Model

A
  • Comparing to the blocking I/O model
    Disadvantage: using select requires two system calls (select and recvfrom) instead of one
    Advantage: we can wait for more than one descriptor to be ready
58
Q

select Function Call

A
  • The select function allows the process to instruct the kernel to either:
    1.Wait for any one of multiple events to occur and to wake up the process only when one or more of these events occurs, or
    2.When a specified amount of time has passed.
  • This means that we tell the kernel what descriptors we are interested in (for reading, writing, or an exception condition) and how long to wait. The descriptors in which we are interested are not restricted to sockets; any descriptor can be tested using select.
59
Q

I/O Blocking

A

socket();
bind() ;
listen();
while
accept();
recv();
send();

  • Simple server has blocking problem
    – Suppose 5 connections accepted (5 times, while has run successfully)
    – Suppose 6th accept() blocks
    – Other connections cannot receive and send
    – Cannot get keyboard input either
60
Q

I/O Multiplexing solution

A
  • select() waits on multiple file descriptors and timeout
  • Returns when any file descriptor
    – Is ready to be read, or
    – Written, or
    – Indicates an error, or
    – Timeout exceeded
  • Advantages
    – Simple
    – Application does not consume CPU cycles while waiting
  • Disadvantages
    – Does not scale to large number of file descriptors
61
Q

select()

A

include <sys/types.h>

#include <sys/socket.h>
int status = select(nfds, &readfds, &writefds, &exceptfds, &timeout);

  • Provided a list of file descriptors to check the status if they are read-ready, write-ready, or have registered an exception
  • Returns the number of ready objects, -1 if error
  • nfds is 1 + largest file descriptor to check
  • Uses bit-vector structure called fd_set to manage list of file descriptors
    – readfds list of descriptors to check if read-ready
    – writefds list of descriptors to check if write-ready
    – exceptfds list of descriptors to check if an exception is registered
  • timeout passed to indicate time after which select returns, even if no ready file descriptors
  • The three middle arguments, readset, writeset, and exceptset (&readfds, &writefds, &exceptfds) specify the descriptors that we want the kernel to test for reading, writing, and exception conditions.
  • select uses descriptor sets, typically an array of integers, with each bit in each integer corresponding to a descriptor.
  • For example, using 32-bit integers, the first element of the array corresponds to descriptors 0 through 31, the second element of the array corresponds to descriptors 32 through 63, and so on. All the implementation details are irrelevant to the application and are hidden in the FD_SET datatype and the following four macros
62
Q

To Be Used With select

A
  • select uses a structure struct fd_set
    – It is just a bit-vector
    – If bit i is set in [readfds, writefds, exceptfds], select will check if file descriptor (i.e. socket) i is ready for [reading, writing, exception]
  • Before calling select
    – FD_ZERO(&fdvar) clears the structure
    – FD_SET(i, &fdvar) to check file descriptor i
  • After calling select
    – int FD_ISSET(i, &fdvar) boolean returns TRUE iff i is “ready”