zoukankan      html  css  js  c++  java
  • TCP连接的建立以及利用tcpdump分析连接建立的过程(转)

    原文地址:http://www.cnblogs.com/coser/archive/2010/12/05/1968812.html

    一、实验目的

    实验1_1

    使用Freebsd/Linux操作系统下的C编译器和网络程序的调试方法,掌握TCP连接建立和终止以及调整缓冲区大小的方法。

    实验1_2

    使用ethereal/TCPDump等抓包工具,截取TCP建立过程中产生的数据包,分析连接建立过程。

    二、实验环境

    操作系统:Ubuntu 10.04 系统

    编辑器:vim

    网络环境:PC1:Ipv4地址10.3.1.210

                    PC2:Ipv4地址 10.3.1.211

                    两台电脑在同一个网段,可以互相通信,能ping通。

    代码语言:c语言

    代码编译器:gcc编译器

    三、实验内容

    1.       设计思路 

    该实验分为两部分:Tcp通信的连接以及利用tcpdump进行抓包,从抓包的内容分析Tcp进行连接的过程。

    第一部分:Tcp连接的建立 

    Server端:

           思路:需要定义两个socket,一个用于监听,一个用于接受客户端传来的socket。定义ipv4地址参数,指定Ip地址和端口号。然后进行bind,bind成功后进行对指定socket的监听。当有客户端进行连接请求时,accept函数会接收到来自Client端的socket。然后Server将输出Client端相关信息,例如Ip地址或是端口号等,在向客户端buffer流写入欢迎信息。最后关闭连接。

     

    Client端:

    思路:定义一个char字符数组,用于接受服务器端,传来的信息。定义一个socket,然后定义指定服务器端Ipv4地址以及端口号。然后client端主动进行connect连接。连接成功后,接受Server端写入的信息,然后逐一读出,并打印在屏幕上。

     

    第二部分:抓包 

    利用tcpdump抓包工具,进行抓包,然后查看抓包内容。通过截取TCP建立过程中产生的数据包,分析连接建立过程。

    四、相关代码

    server:

     
    #include <stdio.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #define MAXSIZE 1024
    int main(int argc , char * * argv )
    {
    char buffer[MAXSIZE];
    int listenfd=socket(AF_INET,SOCK_STREAM,0);//定义socket,指向ipv4地址的字节流套接口

    struct sockaddr_in serverAddr;
    memset(&serverAddr,0,sizeof(serverAddr));//sockAddr_in 进行初始化
    serverAddr.sin_family=AF_INET;
    serverAddr.sin_addr.s_addr=htonl(INADDR_ANY);
    serverAddr.sin_port=htons(2000);
    if(bind(listenfd,(struct sockaddr *) &serverAddr,sizeof(serverAddr))==-1)
    {
    printf("There is an error during binding ");
    return -1;
    }
    else
    {
    printf("Bind successfully!!! ");
    }
    //对listenfd进行监听,从最初建立时的主动套接口(用于进行connect的套接口)转化为被动套接口(接受连接)
    listen(listenfd,100);//第二个参数为套接口排队的最大连接个数
    int connectfd;
    socklen_t addrlen;
    struct sockaddr_in connectAddr;
    memset(&connectAddr,0,sizeof(connectAddr));
    printf("Be ready to accept a connection! ");
    while(1)
    {
    connectfd=accept(listenfd,(struct sockAddr * )&connectAddr,&addrlen);//接受client端一个请求的socket
    char * clientAddress=inet_ntop(AF_INET,&connectAddr.sin_addr,buffer,sizeof(buffer));//获取客户端的ip地址
    int clientPort=connectAddr.sin_port;//获取客户端的端口号
    //打印出客户端的ip地址以及端口号
    printf("Connect from %s , port %d ",clientAddress,clientPort);
    snprintf(buffer,sizeof(buffer),"%s","Welcome to server! ");

    write(connectfd,buffer,sizeof(buffer));
    close(connectfd);
    }
    close(listenfd); //虽然因为上面有while(true),这行永远都执行不了,但是时刻注意关闭socket连接应该是个好习惯。

    return 0;
    }
     

    client:

     

     
    #include <stdio.h>
    #include <string.h>
    #include <arpa/inet.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #define MAXLINE 4096
    int main( int argc , char * * argv )
    {
    int sockfd , n ;
    char recvline[ MAXLINE + 1];
    struct sockaddr_in servaddr;
    if( ( sockfd = socket( AF_INET , SOCK_STREAM , 0 ) ) < 0 ) {
    printf( "socket error " );
    exit( 1 );
    }
    memset( &servaddr , 0 , sizeof( servaddr ) );
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons( 2000 );//指定Server端的端口号
    char * serverAddress="127.0.0.1";
    //判断指定的ip地址是否有错误
    if( inet_pton( AF_INET ,serverAddress , &servaddr.sin_addr ) <= 0 ) {
    printf( "inet_pton error for %s " , serverAddress );
    exit( 1 );
    }
    if( connect( sockfd , (struct sockaddr *)&servaddr , sizeof( servaddr ) ) < 0 ) {
    printf( "connect error " );
    exit( 1 );
    }
    while( ( n = read( sockfd , recvline , MAXLINE ) ) > 0 ) {
    recvline[ n ] = 0;
    if( fputs( recvline , stdout ) == EOF ) {
    printf( "fputs error " );
    exit( 1 );
    }
    }
    if( n < 0 ) {
    printf( "read error " );
    exit( 1 );
    }
    exit( 0 );
    }
     

    编译代码: 

    Gcc Server.c –o server

    Gcc Client.c –o client

     

    监听抓包代码: 

    sudo tcpdump –s 0 –w socketlog host 10.3.1.210 and host 2000

    读取抓包文件代码:

     sudo tcpdump –r socketlog –A >> log

     vi log

     操作过程

    1.在Server端,启动tcpdump进行抓包。在Client发出一个连接请求,并进行一次实验一的连接。

    2.读取获取的包,并将其放入一个log文件中,用以分析。

    3.读取log文件。

     

     

    分析与结论: 

           从抓包的文件可以看出,此次通信,Server端获取到了所有的package。不仅如此,我们也发现了,通信的内容并没有进行加密,而是明文的传送,因为我们成功获取了Server端发给Client的“Welcome to server”的明文信息。 

           通过包中的内容,我们不难分析出Tcp通信的连接过程。 

    1.      Client端发送SYN,请求进行连接。 

    2.      Server端回复ACK ,MSS=1460

    3.      Client端回复ACK,自此TCP连接建立的三次握手完成。 

    4.      Server端发送数据 请求ACK

    5.      Client端读取数据,应答ACK

    6.      Server端首先关闭连接,FIN

    7.      Client端回复ACK

    8.      Server端 回复ACK 连接自此关闭

  • 相关阅读:
    【DNN发布包解释】package 包裹
    数据仓库 SSIS
    【DNN 系列】 添加模块后不显示
    GridView 绑定 ObjectDataSource
    【DNN 系列】 MVC 分页
    关于一级指针和二级指针的简单见解
    高效使用Vector
    关于autoptr
    (转)Win10 + VMware-CentOS7文件共享、网络连接
    Linux 笔记
  • 原文地址:https://www.cnblogs.com/kwseeker-bolgs/p/4357206.html
Copyright © 2011-2022 走看看