版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p> 《計算機網絡》課程設計</p><p> 題 目 數(shù)據包發(fā)送和接受程序的實現(xiàn) </p><p> 學 院 計算機學院 </p><p> 2012年12月21日</p><p> 數(shù)據包發(fā)送和接受程序的實現(xiàn)</p><p><b> 一、設計題
2、目與要求</b></p><p><b> 1.設計題目</b></p><p><b> 發(fā)送TCP數(shù)據包</b></p><p><b> 2.設計要求</b></p><p> 本設計的功能是填充一個TCP數(shù)據包,并發(fā)送給目的主機。</p>
3、<p> 1)以命令行形式運行:SendTCP source_ip source_port dest_ip dest_port,其中SendTCP是程序名,source_ip為源端IP地址,source_port為源端口號,dest_ip為目的地址,dest_port為目的端口號。</p><p> 2)其他的TCP頭部參數(shù)請自行設定。</p><p> 3)數(shù)據字段為
4、“This is my homework of network,I am happy!”。</p><p> 4)成功發(fā)送后在屏幕上輸出“send OK”。</p><p><b> 三、詳細設計</b></p><p> 本課程設計的目標是發(fā)送一個TCP數(shù)據包,可以利用原始套接字來完成這個工作。整個程序由初始化原始套接字和發(fā)送TCP數(shù)據
5、包兩個部分組成。</p><p> 當應用進程需要通過TCP發(fā)送時,它就將此應用層報文傳送給執(zhí)行TCP協(xié)議的傳輸實體。TCP傳輸實體將用戶數(shù)據加上TCP報頭,形成TCP數(shù)據包,在TCP數(shù)據包上增加IP頭部,形成IP包。如圖-1顯示的是TCP數(shù)據包和IP包得關系。TCP協(xié)議的數(shù)據傳輸單位稱為報文段,其格式如圖-2所示。報文段報頭的長度是20B~60B,選項部分長度最多為40B。TCP報文段主要包括以下字段。<
6、;/p><p> 端口號:端口號字段包括源端口號和目的端口號。每個端口號的長度是16位,分別表示發(fā)送該TCP包的應用進程的端口號和接收該TCP包的應用進程的端口號。</p><p> 圖-1 TCP數(shù)據包加上IP報頭形成IP包</p><p> 序號:長度為32位。由于TCP協(xié)議是面向數(shù)據流的,它所傳送的報文段可以視為連續(xù)的數(shù)據流,因此需要給每一字節(jié)編號。序號字
7、段的“序號”指的是本報文段數(shù)據的第一個字節(jié)的序號。</p><p> 確認號:該字段的長度為32位,它表示接收端希望接收下一個TCP包的第一個字節(jié)的序號。</p><p> 報文長度:該字段長度為4位。TCP報文長度是以4B為一個單元來計算的,實際上報文長度在20B~60B之間。因此這個字段的值在5~15之間。</p><p> 圖-2 TCP數(shù)據包頭部的格式
8、</p><p> 保留:長度為6位,留做今后使用,目前全部置0.</p><p> 控制:這個字段定義了6種不同的標志,每一個標志占一位,在同一時間可以設置一位或多位。URG位為1時,表明應盡快把數(shù)據傳送給應用程序,否則表明允許數(shù)據在緩存中存放一段時間。RST位為1時,表明要強制切斷連接。SYN位為1時,表明有確立連接的請求,這時,把序號字段的初始值作為序號字段的值,以便開始通信。F
9、IN位為1時,表明發(fā)送放已經沒有數(shù)據發(fā)送了。</p><p> 窗口大?。洪L度為16位,指向必須緊急處理的數(shù)據的位置,因此最多能夠傳送的數(shù)據為65535B。</p><p> 緊急指針:該字段長度為16,指向必需緊急處理的位置,只有當標志URG=1時緊急指針才生效。從TCP報頭后面的報文數(shù)據開始,到緊急指針所指出長度的數(shù)據,就是必須緊急處理的數(shù)據。</p><p&g
10、t; 選項: 該字段可以多達40B,包括單字節(jié)選項和多字節(jié)選項。</p><p> 校驗和:該字段長度為16位,校驗和的校驗范圍包括偽頭部,TCP報頭以及應用層來的數(shù)據。其計算方法與IP協(xié)議頭部校驗和的計算方法一樣。偽頭部為12B,它本身并不是TCP數(shù)據包的真頭部,只是在計算校驗和時,臨時和TCP數(shù)據包連接在一起。偽頭部的格式如圖-3所示</p><p> 0
11、 8 16 24 31</p><p> 創(chuàng)建一個原始套接字,并設置IP頭選項</p><p> SOCKET sock; sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP); 或者: sock=WSASoccket(AF_INET,SOCK_RAW,IPPROTO_I
12、P,NULL,0,WSA_FLAG_OVERLAPPED); 這里,設置了SOCK_RAW標志,表示我們聲明的是一個原始套接字類型。</p><p> 為使用發(fā)送接收超時設置,必須將標志位置位置為WSA_FLAG_OVERLAPPED。在本課程設計中,發(fā)送TCP包時隱藏了自己的IP地址,因此我們要自己填充IP頭,設置IP頭操作選項。其中flag設置為ture,并設定 IP_HDRINCL 選項,表明自己來構
13、造IP頭。setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char *)&Flag, sizeof(Flag));</p><p> int timeout=1000;</p><p> setsockopt(sock, SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout, sizeof(timeout))
14、;</p><p> 在這里我們使用基本套接字SOL_SOCKET,設置SO_SNDTIMEO表示使用發(fā)送超時設置,超時時間設置為1000ms。</p><p> 構造IP頭和TCP頭</p><p> 這里, IP頭和TCP頭以及TCP偽部的構造請參考下面它們的數(shù)據結構。</p><p> typedef struct _iphdr
15、 //定義IP首部 </p><p> { UCHAR h_lenver; //4位首部長度+4位IP版本號 UCHAR tos; //8位服務類型TOS USHORT total_len; //16位總長度(字節(jié)) USHORT ident; //16位標識 USHORT frag_and_flags; //3位標志位 UCHAR t
16、tl; //8位生存時間 TTL UCHAR proto; //8位協(xié)議 (TCP, UDP 或其他) USHORT checksum; //16位IP首部校驗和 ULONG sourceIP; //32位源IP地址 ULONG destIP; //32位目的IP地址 </p><p> }IP_HEADER; </p>&l
17、t;p> typedef struct psd_hdr //定義TCP偽首部 </p><p> { ULONG saddr; //源地址 ULONG daddr; //目的地址 UCHAR mbz; //沒用UCHAR ptcl; //協(xié)議類型 USHORT tcpl; //TCP長度 </p><p&
18、gt; }PSD_HEADER; </p><p> typedef struct _tcphdr //定義TCP首部 </p><p> { USHORT th_sport; //16位源端口 USHORT th_dport; //16位目的端口 ULONG th_seq; //32位序列號 ULONG th_ack;
19、 //32位確認號 UCHAR th_lenres; //4位首部長度/6位保留字 UCHAR th_flag; //6位標志位 USHORT th_win; //16位窗口大小 USHORT th_sum; //16位校驗和 USHORT th_urp; //16位緊急數(shù)據偏移量 </p><p> }TCP_HEADER; </p>&l
20、t;p> 3.計算校驗和的子函數(shù)</p><p> 在填充數(shù)據包的過程中,需要調用計算校驗和的函數(shù)checksum兩次,分別用于校驗IP頭和TCP頭部(加上偽頭部),其實現(xiàn)代碼如下:</p><p> USHORT checksum(USHORT *buffer, int size) </p><p> { unsigned long cksum=0
21、; while(size >1) { cksum+=*buffer++; size -=sizeof(USHORT); } if(size ) { cksum += *(UCHAR*)buffer; } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >>16); return (USHORT)(~ck
22、sum);</p><p><b> }</b></p><p><b> 4.流程圖</b></p><p><b> 調試分析</b></p><p> 本程序流程簡單,調試過程中沒有出現(xiàn)大的問題。</p><p> 調試過程中沒有出現(xiàn)重大
23、的語法錯誤,主要是運行的結果不理想,和預期的結果有差距。填充數(shù)據包的程序部分是不容易出錯的。至于數(shù)據包的發(fā)送,由于是利用函數(shù)sendto()來實現(xiàn)的,而sendto()是面向UDP的,將協(xié)議類型修改為UDP(Header.proto=IPPROTO_UDP;)后,調試運行成功,問題得到解決。</p><p><b> 調試時,要添加</b></p><p> #i
24、nclude <winsock2.h> </p><p> #include <ws2tcpip.h> </p><p> #pragma comment(lib,"ws2_32.lib")</p><p><b> 不然編譯出錯。</b></p><p><b&g
25、t; 使用說明</b></p><p> 輸入:sendtcp 192.168.1.123 100 192.168.1.124 200 ,然后回車,出現(xiàn)send ok!表示已經正確發(fā)送。</p><p><b> 源代碼</b></p><p> #include <stdio.h> </p>&l
26、t;p> #include <winsock2.h> </p><p> #include <ws2tcpip.h> </p><p> #include <time.h></p><p> #include <windows.h></p><p> #include <s
27、tring.h></p><p> #include <stdlib.h></p><p> #include <iostream.h></p><p> #pragma comment(lib,"ws2_32.lib")</p><p> #define IPVER 4
28、 //IP協(xié)議預定</p><p> #define MAX_BUFF_LEN 65500 //發(fā)送緩沖區(qū)最大值</p><p> typedef struct ip_hdr //定義IP首部 </p><p><b> {</b></p><p> UCHAR h_verlen;
29、 //4位首部長度,4位IP版本號 </p><p> UCHAR tos; //8位服務類型TOS </p><p> USHORT total_len; //16位總長度(字節(jié)) </p><p> USHORT ident; //16位標識 </p><p>
30、; USHORT frag_and_flags; //3位標志位 </p><p> UCHAR ttl; //8位生存時間 TTL </p><p> UCHAR proto; //8位協(xié)議 (TCP, UDP 或其他) </p><p> USHORT checksum; //16位
31、IP首部校驗和 </p><p> ULONG sourceIP; //32位源IP地址 </p><p> ULONG destIP; //32位目的IP地址 </p><p> }IP_HEADER; </p><p> typedef struct tsd_hdr //定義TCP偽首部
32、 </p><p><b> { </b></p><p> ULONG saddr; //源地址</p><p> ULONG daddr; //目的地址 </p><p> UCHAR mbz; //</p><p> UCHAR ptcl;
33、//協(xié)議類型 </p><p> USHORT tcpl; //TCP長度 </p><p> }PSD_HEADER; </p><p> typedef struct tcp_hdr //定義TCP首部 </p><p><b> { </b></p><p> USHORT
34、th_sport; //16位源端口 </p><p> USHORT th_dport; //16位目的端口 </p><p> ULONG th_seq; //32位序列號 </p><p> ULONG th_ack; //32位確認號 </p&
35、gt;<p> UCHAR th_lenres; //4位首部長度/6位保留字 </p><p> UCHAR th_flag; //6位標志位 </p><p> USHORT th_win; //16位窗口大小 </p><p> USHORT th_sum;
36、 //16位校驗和 </p><p> USHORT th_urp; //16位緊急數(shù)據偏移量 </p><p> }TCP_HEADER; </p><p> //CheckSum:計算校驗和的子函數(shù) </p><p> USHORT checksum(USHORT *bu
37、ffer, int size) </p><p><b> { </b></p><p> unsigned long cksum=0; </p><p> while(size >1) </p><p><b> { </b></p><p> cksum+
38、=*buffer++; </p><p> size -=sizeof(USHORT); </p><p><b> } </b></p><p><b> if(size) </b></p><p><b> { </b></p><p>
39、cksum += *(UCHAR*)buffer; </p><p><b> } </b></p><p> cksum = (cksum >> 16) + (cksum & 0xffff); </p><p> cksum += (cksum >>16); </p><p>
40、return (USHORT)(~cksum); </p><p><b> } </b></p><p> int main(int argc, char* argv[]) </p><p><b> { </b></p><p> WSADATA WSAData; </p>
41、<p> SOCKET sock; </p><p> IP_HEADER ipHeader; </p><p> TCP_HEADER tcpHeader; </p><p> PSD_HEADER psdHeader; </p><p> char Sendto_Buff[MAX_BUFF_LEN]; //發(fā)送緩沖
42、區(qū)</p><p> unsigned short check_Buff[MAX_BUFF_LEN]; //檢驗和緩沖區(qū)</p><p> const char tcp_send_data[]={"This is my homework of networt,I am happy!"};</p><p> BOOL flag; </p
43、><p> int rect,nTimeOver; </p><p> if (argc!= 5) </p><p><b> {</b></p><p> printf("Useage: sendtcp soruce_ip source_port dest_ip dest_port \n");
44、</p><p> return false; </p><p><b> } </b></p><p> if (WSAStartup(MAKEWORD(2,2), &WSAData)!=0) </p><p><b> { </b></p><p> p
45、rintf("WSAStartup Error!\n"); </p><p> return false; </p><p><b> } </b></p><p> if((sock=WSASocket(AF_INET,SOCK_RAW,IPPROTO_RAW,NULL,0,WSA_FLAG_OVERLAPPED))
46、==INVALID_SOCKET) </p><p><b> { </b></p><p> printf("Socket Setup Error!\n"); </p><p> return false; </p><p><b> } </b></p>
47、<p> flag=true; </p><p> //設置選項值 IP_HDRINCL為要設置的選項值</p><p> if(setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag))==SOCKET_ERROR) </p><p><b> { <
48、;/b></p><p> printf("setsockopt IP_HDRINCL error!\n"); </p><p> return false; </p><p><b> } </b></p><p> nTimeOver=1000; </p><p&
49、gt; //設置選項值 SO_SNDTIMEO為要設置的選項值</p><p> if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (char*)&nTimeOver, sizeof(nTimeOver))==SOCKET_ERROR) </p><p><b> { </b></p><p
50、> printf("setsockopt SO_SNDTIMEO error!\n"); </p><p> return false; </p><p><b> } </b></p><p><b> //填充IP首部 </b></p><p> ipHead
51、er.h_verlen=(IPVER<<4 | sizeof(ipHeader)/sizeof(unsigned long)); </p><p> ipHeader.tos=(UCHAR)0; </p><p> ipHeader.total_len=htons((unsigned short)sizeof(ipHeader)+sizeof(tcpHeader)+size
52、of(tcp_send_data)); </p><p> ipHeader.ident=0; //16位標識</p><p> ipHeader.frag_and_flags=0; //3位標志位</p><p> ipHeader.ttl=128; //8位生存時間 </p><p> ipHeader.proto=I
53、PPROTO_UDP; //協(xié)議類型</p><p> ipHeader.checksum=0; //檢驗和暫時為0</p><p> ipHeader.sourceIP=inet_addr(argv[1]); //32位源IP地址</p><p> ipHeader.destIP=inet_addr(argv[3]); //32位目的IP地址<
54、/p><p> //計算IP頭部檢驗和</p><p> memset(check_Buff,0,MAX_BUFF_LEN);</p><p> memcpy(check_Buff,&ipHeader,sizeof(IP_HEADER));</p><p> ipHeader.checksum=checksum(check_Buf
55、f,sizeof(IP_HEADER));</p><p> //構造TCP偽首部</p><p> psdHeader.saddr=ipHeader.sourceIP;</p><p> psdHeader.daddr=ipHeader.destIP;</p><p> psdHeader.mbz=0;</p><
56、;p> psdHeader.ptcl=ipHeader.proto;</p><p> psdHeader.tcpl=htons(sizeof(TCP_HEADER)+sizeof(tcp_send_data));</p><p> //填充TCP首部 </p><p> tcpHeader.th_dport=htons(atoi(argv[4]));
57、 //16位目的端口號</p><p> tcpHeader.th_sport=htons(atoi(argv[2])); //16位源端口號 </p><p> tcpHeader.th_seq=0; //SYN序列號</p><p> tcpHeader.th_ack=0;
58、 //ACK序列號置為0</p><p> //TCP長度和保留位</p><p> tcpHeader.th_lenres=(sizeof(tcpHeader)/sizeof(unsigned long)<<4|0); </p><p> tcpHeader.th_flag=2; //修改這里來實現(xiàn)不同的標志位探測,2是SYN,1是/
59、/FIN,16是ACK探測 等等 </p><p> tcpHeader.th_win=htons((unsigned short)16384); //窗口大小</p><p> tcpHeader.th_urp=0; //偏移大小 </p><p> tcpHeader.th_sum=0;
60、 //檢驗和暫時填為0</p><p> //計算TCP校驗和 </p><p> memset(check_Buff,0,MAX_BUFF_LEN);</p><p> memcpy(check_Buff,&psdHeader,sizeof(psdHeader)); </p><
61、p> memcpy(check_Buff+sizeof(psdHeader),&tcpHeader,sizeof(tcpHeader)); </p><p> memcpy(check_Buff+sizeof(PSD_HEADER)+sizeof(TCP_HEADER),tcp_send_data,sizeof(tcp_send_data));</p><p> tcp
62、Header.th_sum=checksum(check_Buff,sizeof(PSD_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data)); </p><p><b> //填充發(fā)送緩沖區(qū)</b></p><p> memset(Sendto_Buff,0,MAX_BUFF_LEN);</p><
63、;p> memcpy(Sendto_Buff,&ipHeader,sizeof(IP_HEADER));</p><p> memcpy(Sendto_Buff+sizeof(IP_HEADER),&tcpHeader,sizeof(TCP_HEADER));</p><p> memcpy(Sendto_Buff+sizeof(IP_HEADER)+sizeo
64、f(TCP_HEADER),tcp_send_data,sizeof(tcp_send_data));</p><p> int datasize=sizeof(IP_HEADER)+sizeof(TCP_HEADER)+sizeof(tcp_send_data);</p><p> //發(fā)送數(shù)據報的目的地址</p><p> SOCKADDR_IN dest
65、; </p><p> memset(&dest,0,sizeof(dest));</p><p> dest.sin_family=AF_INET; </p><p> dest.sin_addr.s_addr=inet_addr(argv[3]); </p><p> dest.sin_port=htons(atoi
66、(argv[4]));</p><p> rect=sendto(sock,Sendto_Buff,datasize, 0,(struct sockaddr*)&dest, sizeof(dest)); </p><p> if (rect==SOCKET_ERROR) </p><p><b> { </b></p>
67、;<p> printf("send error!:%d\n",WSAGetLastError()); </p><p> return false; </p><p><b> } </b></p><p><b> else </b></p><p>
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 計算機網絡課程設計tcp數(shù)據包
- 計算機網絡課程設計---網絡協(xié)議數(shù)據包
- 計算機網絡課程設計-- 解析ip數(shù)據包
- 解析arp數(shù)據包-計算機網絡課程設計
- 計算機網絡課程設計---ip數(shù)據包解析報告
- 計算機網絡課程設計---監(jiān)控ip數(shù)據包流量
- 計算機網絡課程設計---基于wireshark的網絡數(shù)據包內容解析
- 計算機網絡課程設計
- 計算機網絡課程設計
- 計算機網絡課程設計
- 《計算機網絡課程設計》
- 網絡課程設計--發(fā)送tcp數(shù)據包
- 計算機網絡課程設計
- 計算機網絡課程設計
- 計算機網絡課程設計
- 計算機網絡課程設計
- 計算機網絡基礎課程設計--ping程序的實現(xiàn)
- 計算機網絡課程設計-監(jiān)控ip包流量
- 計算機網絡課程設計---網絡設計
- 計算機網絡課程設計---模擬ethernet幀的發(fā)送過程
評論
0/150
提交評論