TCP选项:SO_LINGER和TCP_DEFER_ACCEPT
2015-06-25 13:29
501 查看
SO_LINGER选项:
typedef struct linger
{
u_short l_onoff; //开关,零或者非零
u_short l_linger; //优雅关闭最长时限
} linger;
当调用closesocket关闭套接字时,SO_LINGER将决定系统如何处理残存在套接字发送队列中的数据。处理方式无非两种:丢弃或者将数据继续发送至对端,优雅关闭连接。
1、设置 l_onoff为0,则该选项关闭,l_linger的值被忽略,等于内核缺省情况,close调用会立即返回给调用者,如果可能将会传输任何未发送的数据;
2、设置 l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
3、设置 l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完且被对方确认,之后进行正常的终止序列。
此种情况下,应用程序检查close的返回值是非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。close的成功返回仅告诉我们发送的数据(和FIN)已由对方TCP确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为非阻塞的,它将不等待close完成。
TIME_WAIT的作用是保证在主动关闭端口后,保证数据让对端收到,SO_LINGER选项可以避免端口的状态进入TIME_WAIT状态。
//使用SO_LINGER,close后不进入TIME_WAIT状态
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
setsockopt(serverSocket,SOL_SOCKET, SO_LINGER,(const char *) &linger,sizeof(linger));
当l_onoff非0是。l_linge也非0的时候,套接口在TIME_WAIT上将拖延一段时间,l_linger秒,而不再是2MSL的超时。
选项TCP_DEFER_ACCEPT:
例:
val = 5;
setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val)) ; // val 的单位是秒,
如果打开这个功能,如果kernel 在 val 秒之内还没有收到数据,不会继续唤醒进程,而是直接丢弃连接。
服务器受到一个CONNECT请求后,操作系统不会Accept,也不会创建IO句柄。操作系统应该在若干秒,(但肯定远远大于上面设置的1s) 后,会释放相关的链接。但没有同时关闭相应的端口,所以客户端会一直以为处于链接状态。如果Connect后面马上有后续的发送数据,那么服务器会调用Accept接收这个链接端口。
typedef struct linger
{
u_short l_onoff; //开关,零或者非零
u_short l_linger; //优雅关闭最长时限
} linger;
当调用closesocket关闭套接字时,SO_LINGER将决定系统如何处理残存在套接字发送队列中的数据。处理方式无非两种:丢弃或者将数据继续发送至对端,优雅关闭连接。
l_onoff | l_linger | closesocket行为 | 发送队列 | 底层行为 |
零 | 忽略 | 立即返回 | 保持直至发送完成 | 系统接管套接字并保证将数据发送至对端 |
非零 | 零 | 立即返回 | 立即放弃 | 直接发送RST包,自身立即复位,不用经过2MSL状态。对端收到复位错误号 |
非零 | 非零 | 阻塞直到l_linger时间超时或数据发送完成。(套接字必须设置为阻塞状态) | 在超时时间段内保持尝试发送,若超时则立即放弃 | 超时则同第二种情况,若发送完成则皆大欢喜 |
2、设置 l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;
3、设置 l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间(由l_linger决定)。如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完且被对方确认,之后进行正常的终止序列。
此种情况下,应用程序检查close的返回值是非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。close的成功返回仅告诉我们发送的数据(和FIN)已由对方TCP确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为非阻塞的,它将不等待close完成。
TIME_WAIT的作用是保证在主动关闭端口后,保证数据让对端收到,SO_LINGER选项可以避免端口的状态进入TIME_WAIT状态。
//使用SO_LINGER,close后不进入TIME_WAIT状态
struct linger linger;
linger.l_onoff = 1;
linger.l_linger = 0;
setsockopt(serverSocket,SOL_SOCKET, SO_LINGER,(const char *) &linger,sizeof(linger));
当l_onoff非0是。l_linge也非0的时候,套接口在TIME_WAIT上将拖延一段时间,l_linger秒,而不再是2MSL的超时。
选项TCP_DEFER_ACCEPT:
例:
val = 5;
setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val)) ; // val 的单位是秒,
如果打开这个功能,如果kernel 在 val 秒之内还没有收到数据,不会继续唤醒进程,而是直接丢弃连接。
服务器受到一个CONNECT请求后,操作系统不会Accept,也不会创建IO句柄。操作系统应该在若干秒,(但肯定远远大于上面设置的1s) 后,会释放相关的链接。但没有同时关闭相应的端口,所以客户端会一直以为处于链接状态。如果Connect后面马上有后续的发送数据,那么服务器会调用Accept接收这个链接端口。
相关文章推荐
- TCP/IP协议族-----13、运输层简介
- java基础—网络编程———聊天窗口的建立
- android客户端访问服务端(HttpUtils和Gson)
- TCP/IP协议族-----12、多播和多播路由选择协议
- 网络编程基础【CSS编程】
- TCP/IP协议族-----11、单播路由选择协议(RIP、OSPF和BGP)
- 黑马程序员--网络编程学习2
- 使用fiddler模拟http请求
- linux TCP程序开发(基础)
- httpClient请求跨域服务器实例
- 关于curl java 模拟http请求
- http协议详解
- CNN卷积神经网络应用于人脸识别(详细流程+代码实现)
- TCP和UDP
- TCP/IP协议详解卷1--第一章概述--读书笔记
- TCP/IP协议详解概述
- 虚拟机vmware网络设置
- 6月第2周网络安全报告:高危漏洞数量增加1.4倍
- Java之Socket与HTTP区别
- Android使用HttpURLConnection和HttpClient请求服务器数据