《网络编程》- 第9章 – 套接字的多种可选项
1、套接字可选项
IPPROTO_IP层:IP协议相关事项;
IPPROTO_TCP层:TCP协议相关的事项;
SOL_SOCKET层:套接字相关的通用可选项。
getsockopt() 函数
#include <sys/socket.h>
int getsockopt(int sock, int level, int optname,
void *optval, socklen_t *optlen);
功能:
读取套接字可选项;
参数:
返回值:
成功,返回0; 失败,返回-1。
setsockopt() 函数
#include <sys/socket.h>
int setsockopt(int sockfd, int level, int optname,
const void *optval, socklen_t optlen);
功能:
更改套接字可选项;
参数:
返回值:
成功,返回0; 失败返回 -1。
2、SO_REUSEADDR
位置: 协议层 SOL_SOCKET里。
Time-wait 状态
(这里假设主机A是服务器)
Time-wait时长:
几分钟。
Time-wait发生的时刻:
四次挥手中,在发起方的最后一次挥手过程。
产生的效果:
套接字在经过四次挥手过程后并非立即清除,而是要经过一段时间的 Time-wait状态。
Time-wait的必要性:
如果没有Time-wait,在第四次挥手的时候主机A既下线,此时若第四次挥手传输失败(SEQ5001 ACK 7502),主机B会认为是自己第三次挥手失败,会继续发送(FIN, SER 7501, ACK 5001),但此时主机A已经关闭。
有Time-wait后,主机A在发送第四次挥手后并不会立即关闭,而是等一段时间。这样就能有效防止第四次挥手失败了。
缺点:
等待的时间太长,如果因为故障需要紧急重启计算机,而处于Time-wait状态的主机必须要等待几分钟。
解决方法:
在套接字可选项中更改 SO_REUSEADDR的状态,将其改为 TRUE(1)。
optlen = sizeof(option);
option = TRUE;
setsockopt( serv_sock, SOL_SOCKET, SO_REUSEADDR, (void *) &option, optlen );
3、TCP_NODELAY
位置: 协议层 IPPROTO_TCP里。
Nagle 算法
特点:
在数据交换过程:TCP套接字默认使用Nagle算法来交换数据。因此最大限度地进行缓冲,直到收到ACK才进行下一步操作。这样有效地提高网络传输效率减少了网络流量的混乱传输。(这里说的效率是指准确性)
缺点:
无法提高传输速率,在传输大文件数据时,即便不使用Nagle算法,也会在装满输出缓冲区时传输数据包。这时不仅不会增加数据包的数量,反而要浪费时间等待ACK。
如何禁用Nagle:
将套接字可选项 TCP_NODELAY改为1(真)就行。
int opt_val = 1;
setsockopt( sock, IPPROTO_TCP, TCP_NODELAY,(void *) &opt_val, sizeof(opt_val) );
可以通过 TCP_NODELAY的值查看 Nagle算法的设置状态:
int opt_val;
socklen_t opt_len;
opt_len = sizeof( opt_val );
getsockopt( sock, IPPROTO_TCP, TCO_NODELAY, (void *) &opt_val, &opt_len );
如果正在使用 Nagle算法,opt_val变量中会保存0; 如果禁用,保存1。