c语言 - socket编程(三),tcp_keepalive保持长连接,允许程序使用还在TIME_WAIT状态的端口
getsockopt、setsockopt
int getsockopt(int socket, int level, int optname, void *optval, socklen_t *optlen);
:获取套接字属性
socket
:输入参数,要操作的socket套接字level
:输入参数,协议层:SOL_SOCKET
通用套接字选项、IPPROTO_IP
IP选项、IPPROTO_TCP
TCP选项optname
:输入参数,访问的选项名optval
:输出参数,保存选项的值optlen
:输入参数,指明optval的长度- 返回值:成功返回0,失败返回-1,并设置errno
int setsockopt(int socket, int level, int optname, const void *optval, socklen_t optlen);
:设置套接字属性
socket
:输入参数,要操作的socket套接字level
:输入参数,协议层,同getsockopt()optname
:输入参数,访问的选项名optval
:输入参数,要设置的值optlen
:输入参数,指明optval的长度- 返回值:成功返回0,失败返回-1,并设置errno
常用的socket选项:
SO_REUSEADDR
一般来说,一个端口释放后会等待两分钟之后才能再被使用,这段时间主要消耗在了TIME_WAIT
状态上;
正常情况下只有当socket的状态为CLOSED
的时候才能被重新利用,不过我们可以使用SO_REUSEADDR
选项来重用TIME_WAIT的端口
打开端口重用选项:int on = 1;
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
TCP_NODELAY
TCP_NODELAY 选项的作用是:禁用默认开启的 Nagle 算法。
Nagle 算法
Nagle 算法是以他的发明人 John Nagle 的名字命名的,它用于自动连接许多的小缓冲器消息;这一过程(称为 nagling)通过减少必须发送包的个数来增加网络软件系统的效率。
简单来讲,就是将多段小数据合并为一个数据包,一次性发送,提高网络通信效率。
但是,这个算法对于现代网络来说已经不适用了,因为现在都是强调数据的实时性。
而默认情况下,该算法是启用的,因此,我们需要手动设置 TCP_NODELAY 来禁用它。
禁用 Nagle 算法:int on = 1;
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
SO_KEEPALIVE
tcp保持长连接主要有两种方式:
第一种,使用应用层面的心跳机制,定期发送一个心跳包,检测对方是否还活着
第二种,使用tcp协议自带的keepalive机制,让tcp自己发送心跳包,这里推荐这种方式,更清爽彻底