博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在一个处于CLOSE_WAIT状态下的socket上send数据,对方会毫不留情地RST(对方之前已经调用close发FIN)
阅读量:4141 次
发布时间:2019-05-25

本文共 4343 字,大约阅读时间需要 14 分钟。

        在四次挥手中, 被动关闭的一端进入CLOSE_WAIT状态, 此时, 如果还在这个socket上发送数据, 那么主动关闭(这是说的是close关闭, 而非shundown关闭, 他们有区别, 我们后面再说)的一端会返回RST.

        我们来看看:

        服务端程序为:

 

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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;}

       先启动它。

 

 

       客户端程序为:

 

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(){ int sockClient = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addrSrv; addrSrv.sin_addr.s_addr = inet_addr("10.100.70.140"); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(8765); connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in)); while(1) { #define N 200 char szSendBuf[N] = {0}; for(unsigned int i = 0; i < N; i++) //字符数组最后一个字符不要求是‘\0’ { szSendBuf[i] = 'a'; } int iRet = send(sockClient, szSendBuf, sizeof(szSendBuf) , 0); printf("send size is %d, iRet is %d\n", sizeof(szSendBuf), iRet); getchar(); } close(sockClient); return 0;}

        再启动它。

 

 

        三次握手建立后, 客户端给服务端正常发送数据。 服务端接受到数据后, 调用close来主动关闭链接, 此时客户端进入CLOSE_WAIT状态, 如果客户端继续在这个socket上发送数据, 那么服务端给回RST包, 看看结果:

 

xxxxxx$ ./serveriRet is 200    第一次收200字节iRet is -1     socket已经关闭,所以本次recv返回-1

 

 

xxxxxx$ netstat -nao | grep 8765tcp        0      0 10.100.70.139:41849     10.100.70.140:8765      ESTABLISHED off (0.00/0/0)     三次握手后的状态xxxxxx$ xxxxxx$ xxxxxx$ xxxxxx$ netstat -nao | grep 8765tcp        1      0 10.100.70.139:41849     10.100.70.140:8765      CLOSE_WAIT  off (0.00/0/0)     服务端主动关链接后客户端socket的状态

 

xxxxxx$ ./clientsend size is 200, iRet is 200    第一次发送200字节send size is 200, iRet is 200    变成CLOSE_WAIT后, 继续发送200字节

 

21:21:52.595187 IP 10.100.70.139.41849 > 10.100.70.140.ultraseek-http: Flags [P.], seq 201:401, ack 2, win 56, options [nop,nop,TS val 1559812393 ecr 1559808982], length 200        0x0000:  4500 00fc 80ef 4000 4006 172e 0a64 468b  E.....@.@....dF.        0x0010:  0a64 468c a379 223d aede 4129 a44f 9d3c  .dF..y"=..A).O.<        0x0020:  8018 0038 a2cd 0000 0101 080a 5cf8 d929  ...8........\..)        0x0030:  5cf8 cbd6 6161 6161 6161 6161 6161 6161  \...aaaaaaaaaaaa        0x0040:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x0050:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x0060:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x0070:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x0080:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x0090:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x00a0:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x00b0:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x00c0:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x00d0:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x00e0:  6161 6161 6161 6161 6161 6161 6161 6161  aaaaaaaaaaaaaaaa        0x00f0:  6161 6161 6161 6161 6161 6161 0000 0000  aaaaaaaaaaaa....        0x0100:  0000 0000 0000 0000 0000 0000            ............21:21:52.595378 IP 10.100.70.140.ultraseek-http > 10.100.70.139.41849: Flags [R], seq 2756681020, win 0, length 0        0x0000:  4500 0028 a2a2 4000 4006 f64e 0a64 468c  E..(..@.@..N.dF.        0x0010:  0a64 468b 223d a379 a44f 9d3c 0000 0000  .dF."=.y.O.<....        0x0020:  5004 0000 06bf 0000 0000 0000 0000 0000  P...............        0x0030:  0000 0000 0000 0000                      ........

       我们见到RST了, 很容易理解, 服务端都已经发出FIN表示请求关闭了, 你客户端还发数据过去, 有意义么? 直接给你RST

 

 

 

 

转载地址:http://rjwti.baihongyu.com/

你可能感兴趣的文章
第六章 背包问题——01背包
查看>>
第七章 背包问题——完全背包
查看>>
51nod 分类
查看>>
1136 . 欧拉函数
查看>>
面试题:强制类型转换
查看>>
Decorator模式
查看>>
Template模式
查看>>
Observer模式
查看>>
高性能服务器设计
查看>>
性能扩展问题要趁早
查看>>
MySQL-数据库、数据表结构操作(SQL)
查看>>
OpenLDAP for Windows 安装手册(2.4.26版)
查看>>
图文介绍openLDAP在windows上的安装配置
查看>>
Pentaho BI开源报表系统
查看>>
Pentaho 开发: 在eclipse中构建Pentaho BI Server工程
查看>>
JSP的内置对象及方法
查看>>
android中SharedPreferences的简单例子
查看>>
android中使用TextView来显示某个网址的内容,使用<ScrollView>来生成下拉列表框
查看>>
andorid里关于wifi的分析
查看>>
Spring MVC和Struts2的比较
查看>>