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\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 连接自此关闭

更多相关文章
  • TCP/IP协议--TCP协议概括和TCP连接的建立和终止
    TCP提供一种面向连接的.可靠的字节流服务.面向连接指,发送和接收方在交换数据前必须建立一个TCP连接.顺便说下,一个TCP连接只有两方,因此广播和多播是不能应用于TCP的.字节流指,两个应用程序通过TCP连接交换8bit字节构成的字节流.可靠性:1. 应用数据被分割成TCP认为最适合发送的数据块. ...
  • 服务器tcp连接timewait过多优化及详细分析
    [背景说明]在7层负载均衡上,查询网络状态发现timewait太多,于是开始准备优化事宜整体的拓扑结构,前面是lvs做dr模式的4层负载均衡,后端使用(nginx.or haproxy)做7层负载均衡[优化效果]修改前,建立连接的有29个,timewait的就达到了900个,如下图所示修改后,建立连 ...
  • TCP报文段首部格式:序号:本报文段所发送的数据的第一个字节的序号.确认号ack:期待收到对方下一个报文段的第一个数据字节的序号确认ACK:占1位,仅当ACK=1时,确认号字段才有效.ACK=0时,确认号无效同步SYN:连接建立时用于同步序号.当SYN=1,ACK=0时表示:这是一个连接请求报文段. ...
  • 10.TCP连接的建立与终止
    1.建立连接协议 (1)请求端发送一个SYN段指明客户打算连接的服务器的端口,移机初始序号ISN.这个SYN段为报文段1. (2)服务器发回包含服务器的初始序号的SYN报文段作为应答.同时,将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认.一个SYN将占用一个序号. (3)客户必须将确 ...
  • 字节,而且,如果中间的传输网络的MSS更佳的小的话,这个值还会变得更小.4.TCP的状态迁移图书P182页给出了TCP的状态图,这是一个看起来比较复杂的状态迁移图,因为它包含了两个部分---服务器的状态迁移和客户端的状态迁移,如果从某一个角度出发来看这个图,就会清晰许多,这里面的服务器和客户端都不是 ...
  • TCP连接的建立与终止
    一 TCP是一个面向连接的协议.通常由客户端向服务端发送数据前建立.       连接的建立通过3次握手完成,客户端首先向服务端发送一个SYN,服务端响应一个SYN同时对客户端的SYN返回一个ACK,客户端再对服务端的SYN返回一个确认的ACK.至此一个TCP连接建立完毕.具体过程如下图所示: 从上 ...
  • TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即tcp标志位,有6种标示:SYN(synchronous建立联机)ACK(acknowledgement 确认)PSH(p ...
  • TCP/IP详解学习笔记13--TCP连接的建立与终止
    1.TCP连接的建立            设主机B运行一个服务器进程,它先发出一个被动打开命令,告诉它的TCP要准备接收客户进程的连续请求,然后服务进程就处于听的状态.不断检测是否有客户进程发起连续请求,如有,作出响应.设客户进程运行在主机A中,他先向自己的TCP发出主动打开的命令,表明要向某个I ...
一周排行
  • 屌丝们如何突破屌丝固有的穷人思维
    屌丝们如何突破屌丝固有的穷人思维!看懂的人是财富,看不懂的人是鸡汤!前言:2016年的清明 ...
  • LAMMP环境的搭建
    一.LAMMP简介   LAMMP指的是:Linux(操作系统).Apache(HTTP服 ...
  • 在下面附件里面
  • Gartner:2012年大数据HypeCycle
    2012年7月底,Gartner第一次编制了大数据(Big Data)的HypeCycle ...
  • 转眼间,离开大学校园参加工作已一年.一年来,在各级领导的教导和培养下,在同事们的关心和帮助下,自己的思想.工作.学习等各方面都取得了一定的成绩,个人综合素质也得到了一定的提高,现将本人这一年来的思想.工作.学习情况作 ...
  • Memcache是一个高性能的分布式的内存对象缓存系统,通过在内存里维护一个统一的巨大的hash表,它能够用来存储各种格式的数据,包括图像.视频.文件以及数据库检索的结果等.简单的说就是将数据调用到内存中,然后从内存 ...
  • DOS下常用网络相关命令Arp: 显示和修改"地址解析协议"(ARP) 所使用的到以太网的 IP 或令牌环物理地址翻译 表.该命令只有在安装了 TCP/IP 协议之后才可使用arp -a [ine ...
  • 1.如何查看服务器有哪些存储引擎可以使用?为确定你的MySQL服务器可以用哪些存储引擎,执行如下命令: 代码如下: show engines; 这个命令就能搞定了. 2.如何选择合适的存储引擎?(1)选择标准可以分为 ...
  • 一.启动项——“启动”文件夹 单击“开始→程序”,你会发现一个“启动”菜单,这就是最经典的Windows启动位置,右击“启动”菜单选择“打开”即可将其打开,如所示,其中的程序和快捷方式都会在系统启动时自动运行.最常见 ...
  • C++实现矩阵压缩
    C++实现矩阵压缩 转置运算时一种最简单的矩阵运算.对于一个m*n的矩阵M,他的转置矩阵T ...