您的位置:首页 > 大数据 > 人工智能

在一个处于CLOSE_WAIT状态下的socket上send数据,对方会毫不留情地RST(对方之前已经调用close发FIN)

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

        我们来看看:

        服务端程序为:

#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;
}
       先启动它。

       客户端程序为:

#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 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
= {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$ ./server
iRet is 200    第一次收200字节

iRet is -1     socket已经关闭,所以本次recv返回-1


xxxxxx$ netstat -nao | grep 8765
tcp        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 8765
tcp        1      0 10.100.70.139:41849     10.100.70.140:8765      CLOSE_WAIT  off (0.00/0/0)     服务端主动关链接后客户端socket的状态

xxxxxx$ ./client
send 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐