几种TCP连接中出现RST的情况比较详细.docx

上传人:b****8 文档编号:12407378 上传时间:2023-06-05 格式:DOCX 页数:14 大小:240.33KB
下载 相关 举报
几种TCP连接中出现RST的情况比较详细.docx_第1页
第1页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第2页
第2页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第3页
第3页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第4页
第4页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第5页
第5页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第6页
第6页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第7页
第7页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第8页
第8页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第9页
第9页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第10页
第10页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第11页
第11页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第12页
第12页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第13页
第13页 / 共14页
几种TCP连接中出现RST的情况比较详细.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

几种TCP连接中出现RST的情况比较详细.docx

《几种TCP连接中出现RST的情况比较详细.docx》由会员分享,可在线阅读,更多相关《几种TCP连接中出现RST的情况比较详细.docx(14页珍藏版)》请在冰点文库上搜索。

几种TCP连接中出现RST的情况比较详细.docx

几种TCP连接中出现RST的情况比较详细

几种TCP连接中出现RST的情况(比较详细)

收藏人:

2013-07-02 | 阅:

4725  转:

16  

 |   

  |   

 几种TCP连接中出现RST的情况

17人收藏此文章, 发表于1个月前(2013-05-0411:

40),已有314次阅读,共个评论

目录:

[  ]

应该没有人会质疑,现在是一个网络时代了。

应该不少程序员在编程中需要考虑多机、局域网、广域网的各种问题。

所以网络知识也是避免不了学习的。

而且笔者一直觉得TCP/IP网络知识在一个程序员知识体系中必需占有一席之地的。

在TCP协议中RST表示复位,用来异常的关闭连接,在TCP的设计中它是不可或缺的。

发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓存区的包发送RST包。

而接收端收到RST包后,也不必发送ACK包来确认。

其实在网络编程过程中,各种RST错误其实是比较难排查和找到原因的。

下面我列出几种会出现RST的情况。

1端口未打开

服务器程序端口未打开而客户端来连接。

这种情况是最为常见和好理解的一种了。

去telnet一个未打开的TCP的端口可能会出现这种错误。

这个和操作系统的实现有关。

在某些情况下,操作系统也会完全不理会这些发到未打开端口请求。

比如在下面这种情况下,主机241向主机114发送一个SYN请求,表示想要连接主机114的40000端口,但是主机114上根本没有打开40000这个端口,于是就向主机241发送了一个RST。

这种情况很常见。

特别是服务器程序coredump之后重启之前连续出现RST的情况会经常发生。

当然在某些操作系统的主机上,未必是这样的表现。

比如向一台WINDOWS7的主机发送一个连接不存在的端口的请求,这台主机就不会回应。

2请求超时

曾经遇到过这样一个情况:

一个客户端连接服务器,connect返回-1并且error=EINPROGRESS。

直接telnet发现网络连接没有问题。

ping没有出现丢包。

用抓包工具查看,客户端是在收到服务器发出的SYN之后就莫名其妙的发送了RST。

比如像下面这样:

有89、27两台主机。

主机89向主机27发送了一个SYN,表示希望连接8888端口,主机27回应了主机89一个SYN表示可以连接。

但是主机27却很不友好,莫名其妙的发送了一个RST表示我不想连接你了。

后来经过排查发现,在主机89上的程序在建立了socket之后,用setsockopt的SO_RCVTIMEO选项设置了recv的超时时间为100ms。

而我们看上面的抓包结果表示,从主机89发出SYN到接收SYN的时间多达110ms。

(从15:

01:

到15:

01:

,小数点之后的单位是微秒)。

因此主机89上的程序认为接收超时,所以发送了RST拒绝进一步发送数据。

3提前关闭

关于TCP,我想我们在教科书里都读到过一句话,'TCP是一种可靠的连接'。

而这可靠有这样一种含义,那就是操作系统接收到的来自TCP连接中的每一个字节,我都会让应用程序接收到。

如果应用程序不接收怎么办?

你猜对了,RST。

看两段程序:

01

//

02

03

int main(int argc, char**argv) 

04

05

    int listen_fd,real_fd; 

06

    struct sockaddr_inlisten_addr,client_addr; 

07

    socklen_tlen= sizeof(struct sockaddr_in); 

08

    listen_fd=socket(AF_INET,SOCK_STREAM,0); 

09

    if(listen_fd==-1) 

10

    { 

11

        perror("socketfailed  "); 

12

        return -1; 

13

    } 

14

    bzero(&listen_addr,sizeof(listen_addr)); 

15

    =AF_INET; 

16

    =htonl(INADDR_ANY); 

17

    =htons(SERV_PORT); 

18

    bind(listen_fd,(struct sockaddr*)&listen_addr,len); 

19

    listen(listen_fd,WAIT_COUNT); 

20

    while

(1) 

21

    { 

22

        real_fd=accept(listen_fd,(struct sockaddr*)&client_addr,&len); 

23

        if(real_fd==-1) 

24

        { 

25

            perror("accpetfail "); 

26

            return -1; 

27

        } 

28

        if(fork()==0) 

29

        { 

30

            close(listen_fd); 

31

            char pcContent[4096];

32

            read(real_fd,pcContent,4096);

33

            close(real_fd); 

34

            exit(0);             

35

        } 

36

        close(real_fd); 

37

    }    

38

    return 0; 

39

}

这一段是server的最简单的代码。

逻辑很简单,监听一个TCP端口然后当有客户端来连接的时候fork一个子进程来处理。

注意看的是这一段fork里面的处理:

 

1

char pcContent[4096];

2

read(real_fd,pcContent,4096);

3

close(real_fd);

每次只是读socket的前4096个字节,然后就关闭掉连接。

然后再看一下client的代码:

01

//

02

int main(int argc, char**argv) 

03

04

    int send_sk; 

05

    struct sockaddr_ins_addr; 

06

    socklen_tlen= sizeof(s_addr); 

07

    send_sk=socket(AF_INET,SOCK_STREAM,0); 

08

    if(send_sk==-1) 

09

    { 

10

        perror("socketfailed "); 

11

        return -1; 

12

    } 

13

    bzero(&s_addr, sizeof(s_addr)); 

14

    =AF_INET; 

15

16

    inet_pton(AF_INET,SER_IP,&; 

17

    =htons(SER_PORT); 

18

    if(connect(send_sk,(struct sockaddr*)&s_addr,len)==-1) 

19

    { 

20

        perror("connectfail "); 

21

        return -1; 

22

    } 

23

    char pcContent[5000]={0};

24

    write(send_sk,pcContent,5000);

25

    sleep

(1);

26

    close(send_sk);

27

}

这段代码更简单,就是打开一个socket然后连接一个服务器并发送5000个字节。

刚才我们看服务器的代码,每次只接收4096个字节,那么就是说客户端发送的剩下的4个字节服务端的应用程序没有接收到,服务器端的socket就被关闭掉,这种情况下会发生什么状况呢,还是抓包看一看。

前三行就是TCP的3次握手,从第四行开始看,客户端的49660端口向服务器的9877端口发送了5000个字节的数据,然后服务器端发送了一个ACK进行了确认,紧接着服务器向客户端发送了一个RST断开了连接。

和我们的预期一致。

4在一个已关闭的socket上收到数据

如果某个socket已经关闭,但依然收到数据也会产生RST。

代码如下:

客户端:

01

int main(int argc, char**argv) 

02

03

    int send_sk; 

04

    struct sockaddr_ins_addr; 

05

    socklen_tlen= sizeof(s_addr); 

06

    send_sk=socket(AF_INET,SOCK_STREAM,0); 

07

    if(send_sk==-1) 

08

    { 

09

        perror("socketfailed "); 

10

        return -1; 

11

    } 

12

    bzero(&s_addr, sizeof(s_addr)); 

13

    =AF_INET; 

14

15

    inet_pton(AF_INET,SER_IP,&; 

16

    =htons(SER_PORT); 

17

    if(connect(send_sk,(struct sockaddr*)&s_addr,len)==-1) 

18

    { 

19

        perror("connectfail "); 

20

        return -1; 

21

    } 

22

    char pcContent[4096]={0};

23

    write(send_sk,pcContent,4096);

24

    sleep

(1);

25

    write(send_sk,pcContent,4096);

26

    close(send_sk);

27

服务端:

01

int main(int argc, char**argv) 

02

03

    int listen_fd,real_fd; 

04

    struct sockaddr_inlisten_addr,client_addr; 

05

    socklen_tlen= sizeof(struct sockaddr_in); 

06

    listen_fd=socket(AF_INET,SOCK_STREAM,0); 

07

    if(listen_fd==-1) 

08

    { 

09

        perror("socketfailed  "); 

10

        return -1; 

11

    } 

12

    bzero(&listen_addr,sizeof(listen_addr)); 

13

    =AF_INET; 

14

    =htonl(INADDR_ANY); 

15

    =htons(SERV_PORT); 

16

    bind(listen_fd,(struct sockaddr*)&listen_addr,len); 

17

    listen(listen_fd,WAIT_COUNT); 

18

    while

(1) 

19

    { 

20

        real_fd=accept(listen_fd,(struct sockaddr*)&client_addr,&len); 

21

        if(real_fd==-1) 

22

        { 

23

            perror("accpetfail "); 

24

            return -1; 

25

        } 

26

        if(fork()==0) 

27

        { 

28

            close(listen_fd); 

29

            char pcContent[4096];

30

            read(real_fd,pcContent,4096);

31

            close(real_fd); 

32

            exit(0);             

33

        } 

34

        close(real_fd); 

35

    }    

36

    return 0; 

37

客户端在服务端已经关闭掉socket之后,仍然在发送数据。

这时服务端会产生RST。

总结

总结,本文讲了几种TCP连接中出现RST的情况。

实际上肯定还有无数种的RST发生,我以后会慢慢收集把更多的例子加入这篇文章。

参考文献:

1从TCP协议的原理来谈谈RST攻击 TCP客户-服务器程序例子

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2