TCP連接的建立以及利用tcpdump分析連接建立的過程
一、實驗?zāi)康?/span>
實驗1_1:
使用Freebsd/Linux操作系統(tǒng)下的C編譯器和網(wǎng)絡(luò)程序的調(diào)試方法,掌握TCP連接建立和終止以及調(diào)整緩沖區(qū)大小的方法。
實驗1_2:
使用ethereal/TCPDump等抓包工具,截取TCP建立過程中產(chǎn)生的數(shù)據(jù)包,,分析連接建立過程。
二,、實驗環(huán)境
操作系統(tǒng):Ubuntu 10.04 系統(tǒng)
編輯器:vim
網(wǎng)絡(luò)環(huán)境:PC1:Ipv4地址10.3.1.210
PC2:Ipv4地址 10.3.1.211
兩臺電腦在同一個網(wǎng)段,,可以互相通信,能ping通,。
代碼語言:c語言
代碼編譯器:gcc編譯器
三,、實驗內(nèi)容
<!--[if !supportLists]-->1. <!--[endif]-->設(shè)計思路
該實驗分為兩部分:Tcp通信的連接以及利用tcpdump進行抓包,從抓包的內(nèi)容分析Tcp進行連接的過程,。
第一部分:Tcp連接的建立
Server端:
思路:需要定義兩個socket,,一個用于監(jiān)聽,一個用于接受客戶端傳來的socket,。定義ipv4地址參數(shù),,指定Ip地址和端口號。然后進行bind,bind成功后進行對指定socket的監(jiān)聽,。當有客戶端進行連接請求時,,accept函數(shù)會接收到來自Client端的socket。然后Server將輸出Client端相關(guān)信息,,例如Ip地址或是端口號等,,在向客戶端buffer流寫入歡迎信息。最后關(guān)閉連接,。
Client端:
思路:定義一個char字符數(shù)組,,用于接受服務(wù)器端,傳來的信息,。定義一個socket,,然后定義指定服務(wù)器端Ipv4地址以及端口號。然后client端主動進行connect連接,。連接成功后,,接受Server端寫入的信息,然后逐一讀出,,并打印在屏幕上。
第二部分:抓包
利用tcpdump抓包工具,,進行抓包,,然后查看抓包內(nèi)容。通過截取TCP建立過程中產(chǎn)生的數(shù)據(jù)包,,分析連接建立過程,。
四、相關(guān)代碼
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地址的字節(jié)流套接口 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進行監(jiān)聽,,從最初建立時的主動套接口(用于進行connect的套接口)轉(zhuǎn)化為被動套接口(接受連接) listen(listenfd,100);//第二個參數(shù)為套接口排隊的最大連接個數(shù) 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),這行永遠都執(zhí)行不了,,但是時刻注意關(guān)閉socket連接應(yīng)該是個好習慣,。 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 ); }
編譯代碼:
<!--[endif]--><!--[if !mso]-->
<!--[endif]-->
Gcc Server.c –o server
Gcc Client.c –o client <!--[if !mso]--> | <!--[endif]--><!--[if !mso & !vml]--> |
監(jiān)聽抓包代碼:
<!--[endif]--><!--[if !mso]-->
<!--[endif]-->
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發(fā)出一個連接請求,,并進行一次實驗一的連接。
2.讀取獲取的包,,并將其放入一個log文件中,,用以分析。
3.讀取log文件,。
分析與結(jié)論:
從抓包的文件可以看出,,此次通信,Server端獲取到了所有的package。不僅如此,,我們也發(fā)現(xiàn)了,,通信的內(nèi)容并沒有進行加密,而是明文的傳送,,因為我們成功獲取了Server端發(fā)給Client的“Welcome to server”的明文信息,。
通過包中的內(nèi)容,我們不難分析出Tcp通信的連接過程,。
<!--[if !supportLists]-->1. <!--[endif]-->Client端發(fā)送SYN,,請求進行連接。
<!--[if !supportLists]-->2. <!--[endif]-->Server端回復(fù)ACK ,,MSS=1460
<!--[if !supportLists]-->3. <!--[endif]-->Client端回復(fù)ACK,,自此TCP連接建立的三次握手完成。
<!--[if !supportLists]-->4. <!--[endif]-->Server端發(fā)送數(shù)據(jù) 請求ACK
<!--[if !supportLists]-->5. <!--[endif]-->Client端讀取數(shù)據(jù),,應(yīng)答ACK
<!--[if !supportLists]-->6. <!--[endif]-->Server端首先關(guān)閉連接,,FIN
<!--[if !supportLists]-->7. <!--[endif]-->Client端回復(fù)ACK
<!--[if !supportLists]-->8. <!--[endif]-->Server端 回復(fù)ACK 連接自此關(guān)閉
|