分享
分享赚钱 收藏 举报 版权申诉 / 13

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

  • 上传人:hwpkd79526
  • 文档编号:8021954
  • 上传时间:2019-06-04
  • 格式:DOCX
  • 页数:13
  • 大小:268.84KB
  • 配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    几种TCP连接中出现RST的情况( 比较详细).docx
    资源描述:

    1、几种 TCP 连接中出现 RST 的情况( 比较详细)收藏人:hh37552013-07-02 | 阅:4725 转:16 | 来源 | 分享 几种 TCP 连接中出现 RST 的情况17 人收藏此文章, 我要收藏发表于 1 个月前(2013-05-04 11:40) , 已有 314 次阅读 ,共 0 个评论目录: - 1 端口未打开 2 请求超时 3 提前关闭 4 在一个已关闭的 socket 上收到数据 总结 参考文献:应该没有人会质疑,现在是一个网络时代了。应该不少程序员在编程中需要考虑多机、局域网、广域网的各种问题。所以网络知识也是避免不了学习的。而且笔者一直觉得 TCP/IP 网络

    2、知识在一个程序员知识体系中必需占有一席之地的。在 TCP 协议中 RST 表示复位,用来异常的关闭连接,在 TCP 的设计中它是不可或缺的。发送 RST 包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓存区的包发送 RST 包。而接收端收到 RST 包后,也不必发送 ACK 包来确认。其实在网络编程过程中,各种 RST 错误其实是比较难排查和找到原因的。下面我列出几种会出现 RST 的情况。1 端口未打开服务器程序端口未打开而客户端来连接。这种情况是最为常见和好理解的一种了。去 telnet 一个未打开的 TCP 的端口可能会出现这种错误。这个和操作系统的实现有关。在某些情况下,操作系统也

    3、会完全不理会这些发到未打开端口请求。比如在下面这种情况下,主机 241 向主机 114 发送一个 SYN 请求,表示想要连接主机 114 的 40000 端口,但是主机 114 上根本没有打开 40000 这个端口,于是就向主机 241 发送了一个 RST。这种情况很常见。特别是服务器程序 core dump之后重启之前连续出现 RST 的情况会经常发生。当然在某些操作系统的主机上,未必是这样的表现。比如向一台 WINDOWS7 的主机发送一个连接不存在的端口的请求,这台主机就不会回应。2 请求超时曾经遇到过这样一个情况:一个客户端连接服务器,connect 返回-1 并且 error=EIN

    4、PROGRESS。 直接 telnet 发现网络连接没有问题。ping 没有出现丢包。用抓包工具查看,客户端是在收到服务器发出的 SYN 之后就莫名其妙的发送了 RST。比如像下面这样:有 89、 27 两台主机。主机 89 向主机 27 发送了一个 SYN,表示希望连接 8888端口,主机 27 回应了主机 89 一个 SYN 表示可以连接。但是主机 27 却很不友好,莫名其妙的发送了一个 RST 表示我不想连接你了。后来经过排查发现,在主机 89 上的程序在建立了 socket 之后,用 setsockopt 的SO_RCVTIMEO 选项设置了 recv 的超时时间为 100ms。而我们

    5、看上面的抓包结果表示,从主机 89 发出 SYN 到接收 SYN 的时间多达 110ms。(从 15:01:27.799961 到 15:01:27.961886, 小数点之后的单位是微秒)。因此主机 89 上的程序认为接收超时,所以发送了 RST 拒绝进一步发送数据。3 提前关闭关于 TCP,我想我们在教科书里都读到过一句话,TCP 是一种可靠的连接。 而这可靠有这样一种含义,那就是操作系统接收到的来自 TCP 连接中的每一个字节,我都会让应用程序接收到。如果应用程序不接收怎么办?你猜对了,RST。看两段程序:01 /server.c0203 int main(int argc, char*

    6、 argv) 04 05 int listen_fd, real_fd; 06 struct sockaddr_in listen_addr, client_addr; 07 socklen_t len = sizeof(struct sockaddr_in); 08 listen_fd = socket(AF_INET, SOCK_STREAM, 0); 09 if(listen_fd = -1) 10 11 perror(“socket failed “); 12 return -1; 13 14 bzero( 15 listen_addr.sin_family = AF_INET; 16

    7、 listen_addr.sin_addr.s_addr = htonl(INADDR_ANY); 17 listen_addr.sin_port = htons(SERV_PORT); 18bind(listen_fd,(struct sockaddr *)19 listen(listen_fd, WAIT_COUNT); 20 while(1) 21 22real_fd = accept(listen_fd, (struct sockaddr*) 23 if(real_fd = -1) 24 25 perror(“accpet fail “); 26 return -1; 27 28 if

    8、(fork() = 0) 29 30 close(listen_fd); 31 char pcContent4096;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 pcContent4096;2 read(real_fd,pcContent,4096);

    9、3 close(real_fd);每次只是读 socket 的前 4096 个字节,然后就关闭掉连接。然后再看一下 client 的代码 :01 /client.c02 int main(int argc, char* argv) 03 04 int send_sk; 05 struct sockaddr_in s_addr; 06 socklen_t len = sizeof(s_addr); 07 send_sk = socket(AF_INET, SOCK_STREAM, 0); 08 if(send_sk = -1) 09 10 perror(“socket failed “); 11

    10、 return -1; 12 13 bzero( 14 s_addr.sin_family = AF_INET; 1516 inet_pton(AF_INET,SER_IP, 17 s_addr.sin_port = htons(SER_PORT); 18if(connect(send_sk,(struct sockaddr*) 21 return -1; 22 23 char pcContent5000=0;24 write(send_sk,pcContent,5000);25 sleep(1);26 close(send_sk);27 这段代码更简单,就是打开一个 socket 然后连接一

    11、个服务器并发送 5000 个字节。刚才我们看服务器的代码,每次只接收 4096 个字节,那么就是说客户端发送的剩下的 4 个字节服务端的应用程序没有接收到,服务器端的 socket 就被关闭掉,这种情况下会发生什么状况呢,还是抓包看一看。前三行就是 TCP 的 3 次握手,从第四行开始看,客户端的 49660 端口向服务器的9877 端口发送了 5000 个字节的数据,然后服务器端发送了一个 ACK 进行了确认,紧接着服务器向客户端发送了一个 RST 断开了连接。和我们的预期一致。4 在一个已关闭的 socket 上收到数据如果某个 socket 已经关闭,但依然收到数据也会产生 RST。代码

    12、如下:客户端:01 int main(int argc, char* argv) 02 03 int send_sk; 04 struct sockaddr_in s_addr; 05 socklen_t len = sizeof(s_addr); 06 send_sk = socket(AF_INET, SOCK_STREAM, 0); 07 if(send_sk = -1) 08 09 perror(“socket failed “); 10 return -1; 11 12 bzero( 13 s_addr.sin_family = AF_INET; 1415 inet_pton(AF_

    13、INET,SER_IP, 16 s_addr.sin_port = htons(SER_PORT); 17if(connect(send_sk,(struct sockaddr*) 20 return -1; 21 22 char pcContent4096=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; 0

    14、4 struct sockaddr_in listen_addr, client_addr; 05 socklen_t len = sizeof(struct sockaddr_in); 06 listen_fd = socket(AF_INET, SOCK_STREAM, 0); 07 if(listen_fd = -1) 08 09 perror(“socket failed “); 10 return -1; 11 12 bzero( 13 listen_addr.sin_family = AF_INET; 14 listen_addr.sin_addr.s_addr = htonl(I

    15、NADDR_ANY); 15 listen_addr.sin_port = htons(SERV_PORT); 16bind(listen_fd,(struct sockaddr *) 17 listen(listen_fd, WAIT_COUNT); 18 while(1) 19 20real_fd = accept(listen_fd, (struct sockaddr*) 21 if(real_fd = -1) 22 23 perror(“accpet fail “); 24 return -1; 25 26 if(fork() = 0) 27 28 close(listen_fd); 29 char pcContent4096;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 攻击 http:/ TCP 客户-服务器程序例子 http:/

    展开阅读全文
    提示  道客多多所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:几种TCP连接中出现RST的情况( 比较详细).docx
    链接地址:https://www.docduoduo.com/p-8021954.html
    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    道客多多用户QQ群:832276834  微博官方号:道客多多官方   知乎号:道客多多

    Copyright© 2025 道客多多 docduoduo.com 网站版权所有世界地图

    经营许可证编号:粤ICP备2021046453号    营业执照商标

    1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png



    收起
    展开