tcp连接超时, 那么可能会出现两次握手后, 客户端发RST包
来源:互联网 发布:php为什么要用到apache 编辑:程序博客网 时间:2024/06/03 19:38
先看服务端:
#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <malloc.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/ioctl.h>#include <stdarg.h>#include <fcntl.h>int main(){int sockSrv = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in addrSrv;addrSrv.sin_family = AF_INET;addrSrv.sin_addr.s_addr = INADDR_ANY; addrSrv.sin_port = htons(8765);bind(sockSrv, (const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));listen(sockSrv, 5);struct sockaddr_in addrClient;int len = sizeof(struct sockaddr_in);int sockConn = accept(sockSrv, (struct sockaddr *)&addrClient, (socklen_t*)&len);while(1) { char szRecvBuf[50001] = {0}; int iRet = recv(sockConn, szRecvBuf, sizeof(szRecvBuf) - 1, 0); printf("iRet is %d\n", iRet); getchar();close(sockConn);} while(1);close(sockSrv);return 0;}启动它。
再来看一个带超时时间的connect函数的客户端程序:
#include <unistd.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <errno.h>#include <malloc.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/ioctl.h>#include <stdarg.h>#include <fcntl.h>#include <time.h>int main(int argc, char *argv[]) // 注意输入参数, 带上ip和port, 带上超时参数{ int sockClient = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addrSrv; addrSrv.sin_addr.s_addr = inet_addr(argv[1]); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(atoi(argv[2]));fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK); int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in));printf("connect iRet is %d, errmsg:%s\n", iRet, strerror(errno)); // 返回-1不一定是异常if (iRet != 0) { if(errno != EINPROGRESS){printf("connect error:%s\n",strerror(errno)); } else {int nTime = atoi(argv[3]); // 微秒struct timeval tm = {0, nTime};fd_set wset, rset; FD_ZERO(&wset);FD_ZERO(&rset);FD_SET(sockClient, &wset); FD_SET(sockClient, &rset); int n = select(sockClient + 1, &rset, &wset, NULL, &tm); if(n < 0){ printf("select error, n is %d\n", n); } else if(n == 0) { printf("connect time out\n"); } else if (n == 1) { if(FD_ISSET(sockClient, &wset)) { printf("connect ok!\n"); fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK); } else { printf("unknow error:%s\n", strerror(errno)); } }else{printf("oh, not care now, n is %d\n", n);}} } printf("I am here!\n"); //getchar(); close(sockClient); return 0;}服务端在10.100.70.140机器上, 且正在监听8765端口, 我们来看看客户端的log和握手过程(connect函数的超时为1微秒):
xxxxxx$ ./client 10.100.70.140 8765 1connect iRet is -1, errmsg:Operation now in progressconnect time outI am here!
xxxxxx$ sudo tcpdump -iany port 23456 -Xnlps0tcpdump: verbose output suppressed, use -v or -vv for full protocol decodelistening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes21:43:40.898224 IP 10.100.70.139.51256 > 10.100.70.140.aequus: Flags [S], seq 948273802, win 14280, options [mss 1428,sackOK,TS val 1560139469 ecr 0,nop,wscale 8], length 0 0x0000: 4500 003c 5447 4000 4006 4496 0a64 468b E..<TG@.@.D..dF. 0x0010: 0a64 468c c838 5ba0 3885 828a 0000 0000 .dF..8[.8....... 0x0020: a002 37c8 a20d 0000 0204 0594 0402 080a ..7............. 0x0030: 5cfd d6cd 0000 0000 0103 0308 0000 0000 \............... 0x0040: 0000 0000 0000 0000 0000 0000 ............21:43:40.898426 IP 10.100.70.140.aequus > 10.100.70.139.51256: Flags [S.], seq 802450158, ack 948273803, win 14160, options [mss 1428,sackOK,TS val 1560138227 ecr 1560139469,nop,wscale 8], length 0 0x0000: 4500 003c 0000 4000 4006 98dd 0a64 468c E..<..@.@....dF. 0x0010: 0a64 468b 5ba0 c838 2fd4 6aee 3885 828b .dF.[..8/.j.8... 0x0020: a012 3750 9277 0000 0204 0594 0402 080a ..7P.w.......... 0x0030: 5cfd d1f3 5cfd d6cd 0103 0308 0000 0000 \...\........... 0x0040: 0000 0000 0000 0000 0000 0000 ............21:43:40.898450 IP 10.100.70.139.51256 > 10.100.70.140.aequus: Flags [R], seq 948273803, win 0, length 0 0x0000: 4500 0028 04e5 4000 4006 940c 0a64 468b E..(..@.@....dF. 0x0010: 0a64 468c c838 5ba0 3885 828b 0000 0000 .dF..8[.8....... 0x0020: 5004 0000 2f18 0000 0000 0000 0000 0000 P.../........... 0x0030: 0000 0000 0000 0000 ........看到RST了。
分析下, syn/ack包是在1微秒之后到达的, 所以客户端的select会超时, 代码走入超时逻辑, 等syn/ack到达时, 客户端代码中的超时逻辑中, 执行了close socket的操作。 于是可以这么认为, 经历两次握手后, 客户端调用close socket, 此时发送了RST.
OK, 不多说。
阅读全文
1 0
- tcp连接超时, 那么可能会出现两次握手后, 客户端发RST包
- TCP连接异常终止(RST包)
- TCP连接中出现RST的情况
- 为什么三次握手建立后, 客户端突然发来一个RST ?
- TCP建立连接为什么是三次握手而不是两次握手
- RST包 - TCP/IP
- tcp rst 出现场景
- TCP中出现RST包的几种情况
- 几种TCP连接中出现RST的情况
- 几种TCP连接中出现RST的情况
- 几种TCP连接中出现RST的情况
- 原 几种TCP连接中出现RST的情况
- 几种TCP连接中出现RST的情况
- 几种TCP连接中出现RST的情况
- 几种TCP连接中出现RST的情况
- 几种TCP连接中出现RST的情况
- 几种TCP连接中出现RST的情况
- 几种TCP连接中出现RST的情况
- fgm实例练习笔记-4.1 setTimeout应用
- 【面经笔记】STL库的介绍
- FPGA基础设计(二):PS2键盘控制及短按、长按
- 开发板上修改时间方法date命令【转】
- bzoj 2658: [Zjoi2012]小蓝的好友(mrx) treap+扫描线
- tcp连接超时, 那么可能会出现两次握手后, 客户端发RST包
- android studio 开启multidex支持
- 360个人图书馆防复制
- Springboot配置文件之yaml
- 【GDKOI2012模拟02.01】矩阵
- Python问题:AttributeError: '_csv.reader' object has no attribute 'next' 以及UnicodeDecodeError: 'gbk' co
- HDU-4823(计算几何)
- Maven学习笔记(十一)-创建自定义的archetype(项目模板)
- Java学习笔记---HTTP协议