网络编程(10)—— 通过设置可选项取消socket的TImeWait状态以及开启Nagle算法
来源:互联网 发布:支付宝绑定淘宝账号 编辑:程序博客网 时间:2024/04/29 22:09
一、Time_Wait状态。
我们先回顾一下之前学过的socket断开连接时的四次握手过程:第一次握手:主机A向主机B发送FIN,提出断开连接的请求。
第二次握手:主机B接收到请求后向主机A传递ACK
第三次握手:主机B端向主机A发送FIN.
第四次握手:主机A向主机B发送ACK
发起断开连接请求的主机A在完成第四次握手之后,会进入Time_Wait状态,此时其并没有完全的断开连接,而是在一段时间内保持Time_Wait状态。目的主要是防止第四次握手的数据包丢失,没有传递到主机B时,B会重新传递第三次握手的FIN,而此时保持在Time_Wait状态的主机A会重新发送第四次握手的数据包以保证主机B也能正常的断开连接。
socket在TImeWait状态时,由于已经占用了端口号,当前端口号无法在这段时间内被重复使用.这就是我们有时候用Ctrl+C强制停止和客户端连接过的服务器端时,发生在启动服务器会出现bind error的现象的原因。因为谁发起断开连接的请求谁就会在第四次握手结束后进入Time_Wait的状态。当我们使用Ctrl+C强制停止服务器端的连接时,服务器会向客户端发起断开连接的请求,当进入Time_Wait状态后,此时的端口仍被服务器的socket占据着,因此我们重新服务器时运来的断开会出现bind error的现象。
opelen=sizeof(option);option=1;setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(void*)&option,optlen);
option=1,设置Time_Wait状态下将可将端口号重新分配给新的套接字。
option=0,缺省值,设置Time_Wait状态下将不可将端口号重新分配给新的套接字。
注意:设置时一定要在bind之前设置才会生效!!!!
二、Nagle算法
Nagle算法应用于TCP层,是为了解决数据包过多而发生网络过载的问题。它的原理很简单,以传递一个字符串hello为例:
未使用Nagle算法时:
主机A向主机B传递“hello”时,不管主机B有没有回应,依次传递‘h’、‘e’、‘l’、‘l’、‘o’(这里是极端情况,实际上传送时不会一个字节一个字节的传送),这样算上主机B回给主机A的包共用了10个数据包;
使用Nagle算法时:
主机A向主机B传递“hello”时,先传一个‘h’,此时主机A会最大限度的进行缓冲,当收到主机B发回的‘h’的ACK消息时,将缓存的数据‘ello’一起发送给主机B,这样通过4个数据包就完成了发送任务。
在默认情况下,socket在通信时是使用Nagle算法的,我们可以使用setsockopt函数改变这一设置:
opelen=sizeof(option);option=1;setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,(void*)&option,optlen);option=1,缺省值,开启Nagle算法。
option=0,关闭Nagle算法。
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<unistd.h>#include<arpa/inet.h>#include<sys/socket.h>#include<linux/tcp.h>#define TRUE 1#define FLASE 0void error_handling(char* message);int main(int argc,char* argv[]){ int serv_sock,clnt_sock; char message[30]; struct sockaddr_in serv_addr,clnt_addr; int clntAdrLen,strLen,optlen,option; if(argc!=2) { printf("Usage %s <port>\n",argv[0]); exit(1); } //创建socket serv_sock=socket(AF_INET,SOCK_STREAM,0); if(serv_sock==-1) error_handling("socket error"); //设置Time_Wait状态下套接字可重新分配 optlen=sizeof(option); option=TRUE; setsockopt(serv_sock,SOL_SOCKET,SO_REUSEADDR,(void*)&option,optlen); //设置Nagle算法禁用 optlen=sizeof(option); optlen=TRUE; setsockopt(serv_sock,IPPROTO_TCP,TCP_NODELAY,(void*)&option,optlen); //准备通信地址 memset(&serv_addr,0,sizeof(serv_addr)); serv_addr.sin_family=AF_INET; serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); serv_addr.sin_port=htons(atoi(argv[1])); //socket和通信地址的bind if(bind(serv_sock,(struct sockaddr*)&serv_addr,sizeof(serv_addr))!=0) error_handling("bind error"); //监听 if(listen(serv_sock,5)==-1) error_handling("listen error"); //接收连接 clntAdrLen=sizeof(clnt_addr); clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_addr,&clntAdrLen); //读取数据 while((strLen=read(clnt_sock,message,sizeof(message)))!=0) { printf("sizeof(message) = %d\n",sizeof(message)); printf("接收到的数据是:%s 数据长度:%d\n",message,strLen); write(clnt_sock,message,strLen); //write(1,message,strLen); fputs("回送成功。",stdout); fputc('\n',stdout); } close(clnt_sock); close(serv_sock); return 0;}void error_handling(char* message){ fputs(message,stderr); fputc('\n',stderr); exit(1);}
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL10
- 网络编程(10)—— 通过设置可选项取消socket的TImeWait状态以及开启Nagle算法
- 网络编程(9)—— 怎么获取和设置socket的输出\输入缓冲等多种可选项
- 网络编程(27)—— 再谈Nagle算法
- nagle算法在网络编程的作用
- socket 选项 TCP_NODELAY 和 NAGLE 算法
- socket 选项 TCP_NODELAY 和 NAGLE 算法
- socket 选项 TCP_NODELAY 和 NAGLE 算法
- 在linux编程中,以下哪个TCP的套接字选项与nagle算法的开启和关闭有关?----腾讯2016研发工程师在线模拟笔试题
- 网络编程中Nagle算法和Delayed ACK的测试
- 网络编程中Nagle算法和Delayed ACK的测试
- 网络编程中Nagle算法和Delayed ACK的测试
- Python socket编程之(二):socket的选项设置
- 网络编程之nagle算法和TCP_NODELAY
- 网络编程之nagle算法和TCP_NODELAY
- 网络编程之nagle算法和TCP_NODELAY
- 网络编程之nagle算法和TCP_NODELAY
- 网络编程nagle算法和TCP_NODELAY
- 网络编程中的Socket详解---Delayed Ack(Ack确认延迟) && Nagle Algorithm(纳格算法)
- linux内核工程导论-系统调用
- erlang lists模块函数使用大全
- ThinkPHP3.2.3集成PHPExcel,Linux下导出Excel乱码问题终极解决
- Struts2运行过程简介
- 第三周项目1-顺序表的基本运算
- 网络编程(10)—— 通过设置可选项取消socket的TImeWait状态以及开启Nagle算法
- 使用http协议访问网络
- ListView ArrayAdapter
- BasicDataSource Configuration 配置参数(译)
- 第三周项目4-顺序表应用
- hdu 5884 二分 + 前k优化
- 第三周-项目三求集合并集
- mysql锁表测试
- 第三周项目4 顺序表的应用