zoukankan      html  css  js  c++  java
  • 实战:tcp链接rst场景tcpdump分析

    RST为重置报文段,它会导致TCP连接的快速拆迁,且不需要ack进行确认。

    1.针对不存在的端口的连请求

    客户端:

    #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 <sys/types.h>
    #include <sys/wait.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <netinet/tcp.h>
    #define MAXLINE 4096
    
    
    int main()
    {
       int sockfd,ret;
       struct sockaddr_in servaddr;
       char sendbuf[32740]={0};
    
       sockfd=socket(AF_INET,SOCK_STREAM,0);
       bzero(&servaddr,sizeof(servaddr));
       servaddr.sin_family=AF_INET;
       servaddr.sin_port=htons(8888);
       servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    
    
       ret=connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
       printf("ret=%d
    ",ret);
       write(sockfd,sendbuf,sizeof(sendbuf)+1);
    
    
       getchar();
       close(sockfd);
       return 0;
    }
    

    编译并运行,此时没有服务端在8888端口进行监听,tcpdump抓包看。

    07:19:32.643476 IP 127.0.0.1.49028 > 127.0.0.1.ddi-tcp-1: Flags [S], seq 1270070893, win 65495, options [mss 65495,sackOK,TS val 3883769366 ecr 0,nop,wscale 7], length 0
    07:19:32.643491 IP 127.0.0.1.ddi-tcp-1 > 127.0.0.1.49028: Flags [R.], seq 0, ack 1270070894, win 0, length 0
    

    客户端发起连接,但受到一个RST包。

    2.请求超时

    因为客户端可以设置接收数据的超时时间,当客户端调用connect函数发送SYN时,由于客户端收到服务端的SYN/ACK的时间超过了客户端设置的等待时间,造成接收超时。当服务端的SYN/ACK到达时,客户端回应RST。

    3.提前关闭

    服务端:

    #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 <sys/types.h>
    #include <sys/wait.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #define MAXLINE 4096
     
     
     
    int main()
    {
       int listenfd,acceptfd,n;
       socklen_t  clilen;
       char recvbuf[100]={0};
       struct sockaddr_in cliaddr,servaddr;
     
       listenfd=socket(AF_INET,SOCK_STREAM,0);
       servaddr.sin_family=AF_INET;
       servaddr.sin_port=htons(8888);
       servaddr.sin_addr.s_addr = INADDR_ANY; 
     
       bind(listenfd,(struct sockaddr *)&servaddr,sizeof(struct sockaddr_in));
       listen(listenfd,5);
     
       clilen=sizeof(cliaddr);
       acceptfd=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
     
       
       n=recv(acceptfd,recvbuf,sizeof(recvbuf)-1,0);
       printf("n=%d
    ",n); 
     
       getchar();
       close(acceptfd);
       close(listenfd);
       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>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <netinet/tcp.h>
    #define MAXLINE 4096
     
     
    int main()
    {
       int sockfd,ret;
       struct sockaddr_in servaddr;
       char sendbuf[1000]={0};
     
       sockfd=socket(AF_INET,SOCK_STREAM,0);
       bzero(&servaddr,sizeof(servaddr));
       servaddr.sin_family=AF_INET;
       servaddr.sin_port=htons(8888);
       servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
     
     
     
       ret=connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
       printf("ret=%d
    ",ret);
     
       write(sockfd,sendbuf,sizeof(sendbuf)+1);
     
       getchar();
       close(sockfd);
       return 0;
    }
    

    先启动服务端,再启动客户端。客户端每次发送1001个字节,而服务端只接收了99个字节,还有剩下的字节在接收缓冲区里面。此时先关闭服务端,用tcpdump抓包查看。

    16:28:06.149336 IP 127.0.0.1.49192 > 127.0.0.1.ddi-tcp-1: Flags [S], seq 3096824100, win 65495, options [mss 65495,sackOK,TS val 3916682872 ecr 0,nop,wscale 7], length 0
    16:28:06.149354 IP 127.0.0.1.ddi-tcp-1 > 127.0.0.1.49192: Flags [S.], seq 1491431840, ack 3096824101, win 65483, options [mss 65495,sackOK,TS val 3916682872 ecr 3916682872,nop,wscale 7], length 0
    16:28:06.149372 IP 127.0.0.1.49192 > 127.0.0.1.ddi-tcp-1: Flags [.], ack 1, win 512, options [nop,nop,TS val 3916682872 ecr 3916682872], length 0
    16:28:06.149461 IP 127.0.0.1.49192 > 127.0.0.1.ddi-tcp-1: Flags [P.], seq 1:1002, ack 1, win 512, options [nop,nop,TS val 3916682872 ecr 3916682872], length 1001
    16:28:06.149491 IP 127.0.0.1.ddi-tcp-1 > 127.0.0.1.49192: Flags [.], ack 1002, win 528, options [nop,nop,TS val 3916682872 ecr 3916682872], length 0
    16:28:07.699933 IP 127.0.0.1.ddi-tcp-1 > 127.0.0.1.49192: Flags [R.], seq 1, ack 1002, win 528, options [nop,nop,TS val 3916684423 ecr 3916682872], length 0
    

    服务端没有将数据全部接收完成,然后就关闭了,所以服务端产生了一个RST。

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

    #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 <sys/types.h>
    #include <sys/wait.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #define MAXLINE 4096
     
     
     
    int main()
    {
       int listenfd,acceptfd,n;
       socklen_t  clilen;
       char recvbuf[100]={0};
       struct sockaddr_in cliaddr,servaddr;
     
       listenfd=socket(AF_INET,SOCK_STREAM,0);
       servaddr.sin_family=AF_INET;
       servaddr.sin_port=htons(8888);
       servaddr.sin_addr.s_addr = INADDR_ANY; 
     
       bind(listenfd,(struct sockaddr *)&servaddr,sizeof(struct sockaddr_in));
       listen(listenfd,5);
     
       clilen=sizeof(cliaddr);
       acceptfd=accept(listenfd,(struct sockaddr *)&cliaddr,&clilen);
     
       
     
       getchar();
       close(acceptfd);
       close(listenfd);
       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>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <signal.h>
    #include <netinet/tcp.h>
    #define MAXLINE 4096
     
     
    int main()
    {
       int sockfd,ret;
       struct sockaddr_in servaddr;
       char sendbuf[1000]={0};
     
       sockfd=socket(AF_INET,SOCK_STREAM,0);
       bzero(&servaddr,sizeof(servaddr));
       servaddr.sin_family=AF_INET;
       servaddr.sin_port=htons(8888);
       servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
     
     
     
       ret=connect(sockfd,(struct sockaddr *)&servaddr,sizeof(servaddr));
       printf("ret=%d
    ",ret);
     
       getchar();
       write(sockfd,sendbuf,sizeof(sendbuf)+1);
     
       getchar();
       close(sockfd);
       return 0;
    }
    

    先打开服务端,在打开客户端。然后关闭服务端,在客户端按下回车键键,用tcpdump抓包查看结果。

    16:44:16.226353 IP 127.0.0.1.49194 > 127.0.0.1.ddi-tcp-1: Flags [S], seq 3249455833, win 65495, options [mss 65495,sackOK,TS val 3917652949 ecr 0,nop,wscale 7], length 0
    16:44:16.226370 IP 127.0.0.1.ddi-tcp-1 > 127.0.0.1.49194: Flags [S.], seq 1092997986, ack 3249455834, win 65483, options [mss 65495,sackOK,TS val 3917652949 ecr 3917652949,nop,wscale 7], length 0
    16:44:16.226387 IP 127.0.0.1.49194 > 127.0.0.1.ddi-tcp-1: Flags [.], ack 1, win 512, options [nop,nop,TS val 3917652949 ecr 3917652949], length 0
    16:44:18.402946 IP 127.0.0.1.ddi-tcp-1 > 127.0.0.1.49194: Flags [F.], seq 1, ack 1, win 512, options [nop,nop,TS val 3917655126 ecr 3917652949], length 0
    16:44:18.403887 IP 127.0.0.1.49194 > 127.0.0.1.ddi-tcp-1: Flags [.], ack 2, win 512, options [nop,nop,TS val 3917655127 ecr 3917655126], length 0
    16:44:20.376861 IP 127.0.0.1.49194 > 127.0.0.1.ddi-tcp-1: Flags [P.], seq 1:1002, ack 2, win 512, options [nop,nop,TS val 3917657100 ecr 3917655126], length 1001
    16:44:20.376874 IP 127.0.0.1.ddi-tcp-1 > 127.0.0.1.49194: Flags [R], seq 1092997988, win 0, length 0
    

    客户端和服务端建立连接之后,服务端就关闭了。此时客户端再向服务端发送数据,此时服务端返回RST。

  • 相关阅读:
    linux加载和卸载模块
    java 面试题之银行业务系统
    java 面试题之交通灯管理系统
    java 实现类似spring的可配置的AOP框架
    分析JVM动态生成的类
    最长上升子序列(模板)
    项目管理模式
    让thinkphp 支持ftp上传到远程,ftp删除
    hdu 1280 前m大的数 哈希
    互联网+脑科学,中国脑计划的机会
  • 原文地址:https://www.cnblogs.com/muahao/p/9257166.html
Copyright © 2011-2022 走看看