《TCP/IP网络编程》第9章 套接字的多种可选项

本章所有示例代码>>github

套接字具有多种特性,这些特性可通过可选项更改。

9.1 套接字可选项和I/O缓冲

1.       套接字的多种可选项




    由上表看出,套接字可选项是分层的。IPPROTO_IP层可选项是IP协议相关事项,IPPROTO_TCP层可选项是TCP协议相关的事项,SOL_SOCKET层是套接字相关的通用可选项。

2.       getsockopt& setsockopt

    可选项的读取(Get)和设置(Set)通过如下两个函数完成。

#include <sys/socket.h>
int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen);

    -sock:            用于查看选项套接字文件描述符;

    -level:           要查看的可选项的协议层;

    -optname:     要查看的可选项名;

    -optval:         保存查看结果的缓冲地址值;

    -optlen:         第四个参数optval传递的缓冲大小。调用函数后,该变量中保存

    通过第四个参数返回的可选项信息的字节数;

#include <sys/socket.h>
int setsockopt(int sock, int level, int optname, const void*optval, socklen_t optlen);

3.       SO_SNDBUF& SO_RCVBUF

    SO_RCVBUF是输入缓冲大小相关可选项,SO_SNDBUF是输出缓冲大小相关可选项。用这2个可选项可以读取当前I/O缓冲大小,也可以进行更改。

    缓冲大小的设置需谨慎处理,系统不会完全按照该函数进行设置,只是通过调用setsockopt函数向系统传递要求的缓冲大小值。

9.2 SO_REUSEADDR

1.       发生地址分配错误(Bind Error)

    服务器端向客户端发生FIN消息(服务器端请求断开连接),如果以这种方式终止程序,那服务器端重新运行时将产生问题。如果用同一端口号重新运行服务器端,会产生“bind()error”错误,并且无法再次运行,等待大约3分钟后才能重新运行服务器端。

2.       Time-wait状态

    只有先断开连接(先发送FIN消息)的主机才经过Time-wait状态,因此,若服务器端先断开连接,则无法重新运行。套接字处在Time-wait状态时,端口正在使用,所以bind错误。

    由于客户端套接字的端口号是任意指定的,客户端每次运行时都会动态分配端口号,所以无需过多关注Time-wait状态。

    考虑SEQ 5001ACK 7502这条消息在传递途中丢失,未能传给主机B,这时会发生什么?重传,所以主机A套接字应处在Time-wait状态等待。

3.       地址再分配

在套接字的可选项中更改SO_REUSEADDR的状态。

SO_REUSEADDR的默认值为0(FALSE),将这个值改为1(TRUE),即可重新分配Time-wait状态下的端口号。

optlen = sizeof(option);
option = TRUE;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)option,optlen);

9.3 TCP_NODELAY

Nagle算法

    为防止因数据包过多而发生网络过载,应用于TCP层。TCP套接字默认使用Nagle算法交换数据,因此最大限度地进行缓冲,直到收到ACK。若不使用Nagle算法,发送过程与ACK接收无关,数据到达缓冲将立即被发送出去,对网络流量(Traffic:指网络负载或混杂程度)产生负面影响。为提高网络传输效率,必须使用Nagle算法。

    但Nagle算法并不是什么时候都适用。根据传输数据的特性,网络流量未受太大影响时,不使用Nagle算法要比使用它时传输速度快。(如,传输大文件数据)

    一般情况下,不使用Nagle算法可以提高传输速度。但如果无条件放弃使用Nagle算法,就会增加过多的网络流量,反而影响传输。

       设置Nagle算法的状态:

int opt_val = 1;
setsockopt(sock,IPPROTO_TCP, TCP_NODELAY, (void*)&opt_val, sizeof(opt_val));

       查看Nagle算法的状态:

int opt_val;
socklen_t opt_len;
opt_len =sizeof(opt_val);
getsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&opt_val, &opt_len);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值