Q: 编写 TCP/SOCK_STREAM 服务程序时,SO_REUSEADDR到底什么意思?
A: 这个套接字选项通知内核,如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息,指明"地址已经使用中"。如果你的服务程序停止后想立即重启,而新套接字依旧使用同一端口,此时 SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不可能。
一个套接字由相关五元组构成,协议、本地地址、本地端口、远程地址、远程端口。SO_REUSEADDR 仅仅表示可以重用本地本地地址、本地端口,整个相关五元组还是唯一确定的。所以,重启后的服务程序有可能收到非期望数据。必须慎重使用 SO_REUSEADDR 选项。
Q:
A: O_NONBLOCK和O_NDELAY所产生的结果都是使I/O变成非搁置模式(non-blocking),在读取不到数据或是写入缓冲区已满会马上return,而不会搁置程序动作,直到有数据或写入完成。
它们的差别在于设立O_NDELAY会使I/O函式马上回传0,但是又衍生出一个问题,因为读取到档案结尾时所回传的也是0,这样无法得知是哪中情况;因此,O_NONBLOCK就产生出来,它在读取不到数据时会回传-1,并且设置errno为EAGAIN。
不过需要注意的是,在GNU C中O_NDELAY只是为了与BSD的程序兼容,实际上是使用O_NONBLOCK作为宏定义,而且O_NONBLOCK除了在ioctl中使用,还可以在open时设定。
Socket描述符选项[SOL_SOCKET]
Socket描述符选项[SOL_SOCKET]
#include |
第一个参数socket是套接字描述符。第二个参数level是被设置的选项的级别,如果想要在套接字级别上设置选项,就必须把level设置为SOL_SOCKET。 option_name指定准备设置的选项,option_name可以有哪些取值,这取决于level,以linux 2.6内核为例(在不同的平台上,这种关系可能会有不同),在套接字级别上(SOL_SOCKET),option_name可以有以下取 值:
SO_DEBUG,打开或关闭调试信息。
SO_REUSEADDR,打开或关闭地址复用功能。
SO_DONTROUTE,打开或关闭路由查找功能。
SO_BROADCAST,允许或禁止发送广播数据。
SO_SNDBUF,设置发送缓冲区的大小。
SO_RCVBUF,设置接收缓冲区的大小。
SO_KEEPALIVE,套接字保活。
SO_OOBINLINE,紧急数据放入普通数据流。
SO_NO_CHECK,打开或关闭校验和。
SO_PRIORITY,设置在套接字发送的所有包的协议定义优先权。Linux通过这一值来排列网络队列。
SO_LINGER,如果选择此选项, close或 shutdown将等到所有套接字里排队的消息成功发送或到达延迟时间后>才会返回. 否则, 调用将立即返回。
SO_PASSCRED,允许或禁止SCM_CREDENTIALS 控制消息的接收。
SO_TIMESTAMP,打开或关闭数据报中的时间戳接收。
SO_RCVLOWAT,设置接收数据前的缓冲区内的最小字节数。
SO_RCVTIMEO,设置接收超时时间。
SO_SNDTIMEO,设置发送超时时间。
SO_BINDTODEVICE,将套接字绑定到一个特定的设备上。
SO_ATTACH_FILTER和SO_DETACH_FILTER。
以上所介绍的都是在SOL_SOCKET层的一些套接字选项,如果超出这个范围, 给出一些不在这一level的选项作为参数,最终会得到- ENOPROTOOPT的返回值。但以上的分析仅限于这些选项对sock-sk的值的影响,这些选项真正如何发挥作用,我们的探索道路 将漫漫其修远。