套接字选项支持对套接字进行设置
1 |
|
示例地址:https://github.com/XBoom/network-ip.git 中的 apps/socket/11/
来看看
应用如下:
-
查看套接字类型,运行结果如下
1
2
3./client
[11/client.c:23 main info] get tcp[1] sock opt :1 4
[11/client.c:27 main info] get udp[2] sock opt :2 4
但是!!! 套接字类型只能在创建时设置,以后不能再改变
-
查看缓冲区大小
1
2
3
4[11/client.c:33 main info] tcp send buff size:16384
[11/client.c:36 main info] tcp recv buff size:131072
[11/client.c:39 main info] udp send buff size:212992
[11/client.c:42 main info] udp recv buff size:212992 -
time-wait
重用1
2
3
4int option = 1;
optlen = sizeof(option);
ret = setsockopt(tcp_sock, SOL_SOCKET, SO_REUSEADDR,
(void *)&option, optlen);time_wait
在四次挥手过程中会等待2msl
时间(大多数系统是 120s),是为了等待最后的ack
未收到。如果服务端发起 Fin,那么最后会因为time_wait
而等待端口释放,那么再异常重启状态下,就需要等待大概 4 分钟端口才能恢复(客户端因为端口是随机分配的,所以不太在意立即释放)。1
net.ipv4.tcp_tw_reuse # 1 表示启用了端口重用,即允许在 TIME_WAIT 状态下的连接所使用的端口被新的连接使用。 0 表示禁止
-
Nagle算法
Nagle算法是一种用于减少小包传输的网络优化算法。它的目标是减少网络上的小型数据包数量,提高网络效率。会等待当前缓冲区中的数据被确认之后才发送新的数据。这有助于避免发送大量的小数据包,从而提高网络的效率
Nagle算法的原理如下:
- 如果长度达到 MSS,则允许发送
- 如果数据包中包含
FIN
(断开连接标致),则允许发送 - 当设置了
TCP_NODELAY
选项,则允许发送,禁止Nagle算法 - 未设置
TCP_CORK
选项时,若所有发送的小数据包(包含长度小于MSS)均被确认,则设置该选项后,内核会尽力把小的数据包拼成一个大的数据包(一个MTU)在发送出去,若到指定时间,一般为200ms,仍未组成一个MTU,也要立刻发送。
1
2
3//禁用 Nagle
int flag = 1;
setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));在某些情况下,Nagle算法可能会导致一定的延迟,特别是对于那些需要低延迟的应用程序。为了避免这种情况,可以通过设置
TCP_NODELAY
选项来禁用Nagle算法,强制立即发送数据(默认是开启的)
粘包 问题的缘由可能发生在发送端也可能发生在接收端:
- 由 Nagle 算法造成的发送端的粘包:当提交一段数据给 TCP 发送时,TCP 并不立刻发送此段数据,而是等待一小段时间看看在等待期间是否还有要发送的数据,若有则会一次把这好几段数据发送出去。
- 接收端接受不及时造成的接收端粘包:TCP 会把接收到的数据存在自己的缓冲区中,然后通应用层取数据。当应用层由于某些原因不能及时地把 TCP 的数据取出来,就会造成 TCP 缓冲区中存放了几段数据
解决粘包
- 定长消息:协议提前约定好包的长度为多少,每当接收端接收到固定长度的字节就确定一个包;
- 消息分隔符:利用特殊符号标志着消息的开始或者结束,例如 HTTP 协议中的换行符;
- 长度前缀:先发送N个字节代表包的大小(注意大端和小端问题),后续解析也按长度读取解析。
参考文档
- 《TCPIP 网络编程》