天天看点

Unix Network Programming Episode 63

‘fcntl’ Function

fcntl stands for “file control” and this function performs various descriptor control

operations. Before describing the function and how it affects a socket, we need to look

at the bigger picture.

The fcntl function provides the following features related to network programming:

  • Nonblocking I/O— We can set the O_NONBLOCK file status flag using the F_SETFL command to set a socket as nonblocking. We will describe nonblocking I/O in Chapter 16(See 9.5).
  • Signal-driven I/O— We can set the O_ASYNC file status flag using the F_SETFL command, which causes the SIGIO signal to be generated when the status of a socket changes. We will discuss this in Chapter 25(See 9.14).
  • The F_SETOWN command lets us set the socket owner (the process ID or process group ID) to receive the SIGIO and SIGURG signals. The former signal is generated when signal-driven I/O is enabled for a socket (Chapter 25(See 9.14)) and the latter signal is generated when new out-of-band data arrives for a socket (Chapter 24(See 9.13)). The F_GETOWN command returns the current owner of the socket.

The term “socket owner” is defined by POSIX. Historically, Berkeley-derived implementations have called this “the process group ID of the socket” because the variable that stores this ID is the so_pgid member of the socket structure (p. 438 of TCPv2).

#include <fcntl.h>
int fcntl(intfd, int cmd, ... /* int arg */ );
           

Each descriptor (including a socket) has a set of file flags that is fetched with the F_GETFL command and set with the F_SETFL command. The two flags that affect a socket are

  • O_NONBLOCK—nonblocking I/O
  • O_ASYNC—signal-driven I/O

Elementary UDP Sockets

Introduction

There are some fundamental differences between applications written using TCP versus those that use UDP. These are because of the differences in the two transport layers: UDP is a connectionless, unreliable, datagram protocol, quite unlike the connection-oriented, reliable byte stream provided by TCP. Nevertheless, there are instances when it makes sense to use UDP instead of TCP, and we will go over this design choice in Section 22.4(See 9.11.4). Some popular applications are built using UDP: DNS, NFS, and SNMP, for example.

‘recvfrom’ and ‘sendto’ Functions

These two functions are similar to the standard read and write functions, but three additional arguments are required.

#include <sys/socket.h>
ssize_t recvfrom(int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);
ssize_t sendto(int sockfd, const void *buff, size_t nbytes, int flags, const struct sockaddr *to, socklen_t addrlen);
           

UDP Echo Server: ‘main’ Function

We will now redo our simple echo client/server from Chapter 5(See 8.3) using UDP. Our UDP client and server programs follow the function call flow that we diagrammed in Figure 8.1(See 8.6.1). Figure 8.2 depicts the functions that are used. Figure 8.3 shows the server main function.

继续阅读