Unix网络编程——chap7

套接字选项

getsockopt和setsockopt函数

1
2
3
4
#include<sys/socket.h>
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t oplen);

getsockopt从optval获取目前的选项设置值,setsockopt则是从optval获得选项待设置的新值

常用套接字选项

SO_KEEPALIVE

在设置keep-alive选项之后,如果套接字的任何一方向上都没有数据交换,TCP会自动向对端发送一个自动探测的分节,这是一个对端必须响应的分节。它会导致以下三种情况:

  • 对端响应期望的ACK;
  • 对端以RST响应,表明对端已经崩溃且重启,套接字的错误被设置为ECONNRESET,套接字关闭;
  • 对端没有响应;TCP将会发送8个探测分节,两两相隔75s,如果还是没有响应,则关闭;

SO_RCVBUF和SO_SNDBUF

每个套接字都会有一个发送缓冲区和接收缓冲区,这两个套接字选项就是用来改变缓冲区的默认大小。

由于TCP的窗口规模是在建立连接时,通过SYN分节与对端交换得到的。所以对于客户,必须在调用connect之前调用;对于服务端,必须在listen之前调用。

SO_REUSEADDR

这个套接字选项有4个不同的作用:

  1. 设置这个选项允许启动一个监听服务器并捆绑其众所周知的端口,即便以前建立的用作该端口作为本地端口的连接仍然存在。

考虑这样的条件

  • 启动监听服务器;
  • 连接请求到达,派生一个子进程提供服务;
  • 监听服务器终止,但子进程仍然在服务着;
  • 重启监听服务器;

因为如果不设置该选项,那重启监听服务器时将不能捆绑之前那个端口。

  1. 允许在同一个端口上启动同一个服务器的多个实例。

  2. 允许单个进程捆绑同一个端口到多个套接字上,只要每次捆绑指定不同的地址即可。这种情况发生希望在一个多目的主机的若干个本地地址上服务连接的TCP服务器进程上。

  3. 完全重复的捆绑,包括IP地址和端口,一般用于支持UDP。

fcntl函数

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

这个函数的目的是执行各种描述符的控制操作,如设置非阻塞式I/O,信号驱动式I/O等等。

开启阻塞式I/O:

1
2
3
4
5
6
int flags;
if((flags=fcntl(fd, F_GETFL, 0)) < 0)
err_sys("F_GETEL error");
flag |= O_NONBLOCK;
if (fcntl(fd, F_SETEL, flags) < 0)
err_sys("F_SETEL error");