TCP连接的建立以及利用tcpdump分析连接建立的过程

TCP连接的建立以及利用tcpdump分析连接建立的过程

一、实验目的

实验1_1

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

 

实验1_2

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

二、实验环境

操作系统:Ubuntu 10.04 系统

编辑器:vim

网络环境:PC1Ipv4地址10.3.1.210

                PC2Ipv4地址 10.3.1.211

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

代码语言:c语言

代码编译器:gcc编译器

三、实验内容

1.       设计思路 

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

第一部分:Tcp连接的建立 

Server端:

       思路:需要定义两个socket,一个用于监听,一个用于接受客户端传来的socket。定义ipv4地址参数,指定Ip地址和端口号。然后进行bindbind成功后进行对指定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\n " );
return - 1 ;
}
else
{
printf(
" Bind successfully!!!\n " );
}
// 对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!\n " );
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 \n " ,clientAddress,clientPort);
snprintf(buffer,
sizeof (buffer), " %s " , " Welcome to server!\n " );

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\n " );
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\n " , serverAddress );
exit(
1 );
}
if ( connect( sockfd , ( struct sockaddr * ) & servaddr , sizeof ( servaddr ) ) < 0 ) {
printf(
" connect error\n " );
exit(
1 );
}
while ( ( n = read( sockfd , recvline , MAXLINE ) ) > 0 ) {
recvline[ n ]
= 0 ;
if ( fputs( recvline , stdout ) == EOF ) {
printf(
" fputs error\n " );
exit(
1 );
}
}
if ( n < 0 ) {
printf(
" read error\n " );
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 连接自此关闭 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值