A. UDP的校驗和計算時數據是怎樣計算的
UDP計算校驗和的方法和計算IP數據報首部校驗和的方法相似。但不同的是:IP數據報的校驗和只檢驗IP數據報的首部,但UDP的校驗和是將首部和數據部分一起都檢驗。在發送端,首先是將全零放入檢驗和欄位。再將偽首部以及UDP用戶數據報看成是由許多16bit的字串接起來。
若UDP用戶數據報的數據部分不是偶數個位元組,則要填入一個全零位元組(即:最後一個基數位元組應是16位數的高位元組而低位元組填0)。然後按二進制反碼計算出這些16bit字的和(兩個數進行二進制反碼求和的運算的規則是:從低位到高位逐列進行計算。
0和0相加是0,0和1相加是1,1和1相加是0但要產生一個進位1,加到下一列。若最高位相加後產生進位,則最後得到的結果要加1)。 將此和的二進制反碼寫入校驗和欄位後,發送此UDP用戶數據報。
在接收端,將收到的UDP用戶數據報連同偽首部(以及可能的填充全零位元組)一起,按二進制反碼求這些16bit字的和。 當無差錯時其結果應全為1。否則就表明有差錯出現, 接收端就應將此UDP用戶數據報丟棄。
(1)計算機網路udp報文分析擴展閱讀:
UDP協議全稱是用戶數據報協議,在網路中它與TCP協議一樣用於處理數據包,是一種無連接的協議。在OSI模型中,在第四層——傳輸層,處於IP協議的上一層。UDP有不提供數據包分組、組裝和不能對數據包進行排序的缺點,也就是說,當報文發送之後,是無法得知其是否安全完整到達的。
UDP用來支持那些需要在計算機之間傳輸數據的網路應用。包括網路視頻會議系統在內的眾多的客戶/伺服器模式的網路應用都需要使用UDP協議。
UDP協議從問世至今已經被使用了很多年,雖然其最初的光彩已經被一些類似協議所掩蓋,但是即使是在今天UDP仍然不失為一項非常實用和可行的網路傳輸層協議。
UDP報文沒有可靠性保證、順序保證和流量控制欄位等,可靠性較差。但是正因為UDP協議的控制選項較少,在數據傳輸過程中延遲小、數據傳輸效率高,適合對可靠性要求不高的應用程序,或者可以保障可靠性的應用程序,如DNS、TFTP、SNMP等。
B. 什麼是UDP報文啊
網路傳送數據時的一個分組數據,有tcp報文和udp報文,udp報文用的較少!
C. 如何通過wireshark分析udp報文的協議號
TCP是6,UDP是17
D. 抓包分析ethernet ii 的ipv4 tcp udp三種報文的報頭怎麼分析
用wireshark
E. UDP是什麼,UDP協議及優缺點
UDP,全稱 User Datagram Protocol,中文名稱為用戶數據報協議,主要用來支持那些需要在計算機之間傳輸數據的網路連接。
UDP 協議從問世至今已經被使用了很多年,雖然目前 UDP 協議的應用不如 TCP 協議廣泛,但 UDP 依然是一種非常實用和可行的網路傳輸層協議。尤其是在一些實時性很強的應用場景中,比如網路游戲、視頻會議等,UDP 協議的快速能力更具有獨特的魅力。
UDP 是一種面向非連接的協議,面向非連接指的是在正式通信前不必與對方先建立連接,不管對方狀態就直接發送數據。至於對方是否可以接收到這些數據,UDP 協議無法控制,所以說 UDP 是一種不可靠的協議。
UDP 協議適用於一次只傳送少量數據、對可靠性要求不高的應用環境。
與前面介紹的 TCP 協議一樣,UDP 協議直接位於 IP 協議之上。實際上,IP 協議屬於 OSI 參考模型的網路層協議,而 UDP 協議和 TCP 協議都屬於傳輸層協議。
因為 UDP 是面向非連接的協議,沒有建立連接的過程,因此它的通信效率很高,但也正因為如此,它的可靠性不如 TCP 協議。
UDP 協議的主要作用是完成網路數據流和數據報之間的轉換在信息的發送端,UDP 協議將網路數據流封裝成數據報,然後將數據報發送出去;在信息的接收端,UDP 協議將數據報轉換成實際數據內容。
可以認為 UDP 協議的 socket 類似於碼頭,數據報則類似於集裝箱。碼頭的作用就是負責友送、接收集裝箱,而 socket 的作用則是發送、接收數據報。因此,對於基於 UDP 協議的通信雙方而言,沒有所謂的客戶端和伺服器端的概念。
UDP 協議和 TCP 協議簡單對比如下:
TCP 協議:可靠,傳輸大小無限制,但是需要連接建立時間,差錯控制開銷大。
UDP 協議:不可靠,差錯控制開銷較小,傳輸大小限制在 64 KB以下,不需要建立連接。
?相比較 TCP,UDP 是一種不可靠的網路協議,它在通信實例的兩端各建立一個 socket,但這兩個 socket 之間並沒有虛擬鏈路,它們只是發送、接收數據報的對象。
F. TCP/IP和UDP報文結構和報頭包含的內容!
UDP包
UDP報頭由4個域組成,其中每個域各佔用2個位元組,具體如下:
源埠號
目標埠號
數據報長度
校驗值
UDP協議使用埠號為不同的應用保留其各自的數據傳輸通道。UDP和TCP協議正是採用這一機制實現對同一時刻內多項應用同時發送和接收數據的支持。數據發送一方(可以是客戶端或伺服器端)將UDP數據報通過源埠發送出去,而數據接收一方則通過目標埠接收數據。有的網路應用只能使用預先為其預留或注冊的靜態埠;而另外一些網路應用則可以使用未被注冊的動態埠。因為UDP報頭使用兩個位元組存放埠號,所以埠號的有效范圍是從0到65535。一般來說,大於49151的埠號都代表動態埠。
TCP包
每個tcp都包含源埠號和目標埠號,加上ip頭中的源ip和目的ip,唯一確定一個tcp連接。序號用來標識從tcp發端向tcp收端發送的數據位元組流,它表示在這個報文段中的第一個數據位元組。序號欄位包含由這個主機選擇的該連接的初始序號isn(Initial Sequence Number)。該主機要發送數據的第一個位元組,序號為isn+1,因為syn佔用了一個序號。
IP包
IPV4報頭有12個必需的欄位和可選IP選項欄位,位於要發送的數據之前。如果使用IP層已有的庫或其他組件,一般不必考慮報頭中的大多數欄位,但程序代碼需要提供源端和目的端地址。
1、版本(4比特)
IP協議版本已經經過多次修訂,1981年的RFC0791描述了IPV4,RCF2460中介紹了IPV6。
2、報頭長度(4比特)
報頭長度是報頭數據的長度,以4位元組表示,也就是以32位元組為單位。報頭長度是可變的。必需的欄位使用20位元組(報頭長度為5,IP選項欄位最多有40個附加位元組(報頭長度為15)。
3、服務類型(8比特)
該欄位給出發送進程建議路由器如何處理報片的方法。可選擇最大可靠性、最小延遲、最大吞吐量和最小開銷。路由器可以忽略這部分。
4、數據報長度(16比特)
該欄位是報頭長度和數據位元組的總和,以位元組為單位。最大長度為65535位元組。
5、標識符(16比特)
原是數據的主機為數據報分配一個唯一的數據報標識符。在數據報傳向目的地址時,如果路由器將數據報分為報片,那麼每個報片都有相同的數據標識符。
6、標志(3比特)
標志欄位中有2為與報片有關。
位0:未用。
位1:不是報片。如果這位是1,則路由器就不會把數據報分片。路由器會盡可能把數據報傳給可一次接收整個數據報的網路;否則,路由器會放棄數據報,並返回 差錯報文,表示目的地址不可達。IP標准要求主機可以接收576位元組以內的數據報,因此,如果想把數據報傳給未知的主機,並想確認數據報沒有因為大小的原 因而被放棄,那麼就使用少於或等於576位元組的數據。
位2:更多的報片。如果該位為1,則數據報是一個報片,但不是該分片數據報的最後一個報片;如果該位為0,則數據報沒有分片,或者是最後一個報片。
7、報片偏移(13比特)
該欄位標識報片在分片數據報中的位置。其值以8位元組為單位,最大為8191位元組,對應65528位元組的偏移。
例如,將要發送的1024位元組分為576和424位元組兩個報片。首片的偏移是0,第二片的偏移是72(因為72×8=576)。
8、生存時間(8比特)
如果數據報在合理時間內沒有到達目的地,則網路就會放棄它。生存時間欄位確定放棄數據報的時間。
生存時間表示數據報剩餘的時間,每個路由器都會將其值減一,或遞減需要數理和傳遞數據報的時間。實際上,路由器處理和傳遞數據報的時間一般都小於1S,因此該值沒有測量時間,而是測量路由器之間跳躍次數或網段的個數。發送數據報的計算機設置初始生存時間。
9、協議(8比特)
該欄位指定數據報的數據部分所使用的協議,因此IP層知道將接收到的數據報傳向何處。TCP協議為6,UDP協議為17。
10、報頭檢驗和(16比特)
該字端使數據報的接收方只需要檢驗IP報頭中的錯誤,而不校驗數據區的內容或報文。校驗和由報頭中的數值計算而得,報頭校驗和假設為0,乙太網幀和TCP報文段以及UDP數據報中的可選項都需要進行報文檢錯。
11、源IP地址(32比特)
表示數據報的發送方。
12、目的IP地址(32比特)
表示數據報的目的地。
G. 計算機網路,UDP數據報的校驗和欄位是通過什麼來校驗源和目的IP的呢
其實這是一種加密技術用於對文件內容進行審計的方法,使用 精通讀文件把文件讀到內存中,再對文件內容作一個 MD5 校驗得到一串密碼,就是校驗和。
補充:
1、IP首部校驗和欄位是根據IP首部計算的校驗和碼,它不對首部後面的數據進行計算。ICMP、IGMP、UDP和TCP在它們各自的首部中均含有同時覆蓋首部和數據校驗和碼。
2、IP首部校驗和計算:
為了計算一份數據報的IP檢驗和,首先把檢驗和欄位置為0。然後,對首部中每個16bit進行二進制反碼求和(整個首部看成是由一串16bit的字組成),結果存在檢驗和欄位中。當收到一份IP數據報後,同樣對首部中每個16bit進行二進制反碼的求和。由於接收方在計算過程中包含了發送方存在首部中的檢驗和,因此,如果首部在傳輸過程中沒有發生任何差錯,那麼接收方計算的結果應該為全1。如果結果不是全1(即檢驗和錯誤),那麼IP就丟棄收到的數據報。但是不生成差錯報文,由上層去發現丟失的數據報並進行重傳。
3、TCP和UDP校驗和計算(兩者相同)
校驗和還包含—個96位的偽首標,理論上它位於TCP首標的前面。這個偽首標包含了源地址、目的地址、協議和TCP長度等欄位,這使得TCP能夠防止出現路由選擇錯誤的數據段。這些信息由網際協議(IP)承載,通過TCP/網路介面,在IP上運行的TCP調用參數或者結果中傳遞。
偽首部並非UDP數據報中實際的有效成分。偽首部是一個虛擬的數據結構,其中的信息是從數據報所在IP分組頭的分組頭中提取的,既不向下傳送也不向上遞交,而僅僅是為計算校驗和。
這樣的校驗和,既校驗了UDP用戶數據的源埠號和目的埠號以及UDP用戶數據報的數據部分,又檢驗了IP數據報的源IP地址和目的地址。(偽報頭保證UDP和TCP數據單元到達正確的目的地址。因此,偽報頭中包含IP地址並且作為計算校驗和需要考慮的一部分。最終目的端根據偽報頭和數據單元計算校驗和以驗證通信數據在傳輸過程中沒有改變而且到達了正確的目的地址。
H. 如何分析udp報文,從而獲取源地址
1、寫了一個UDP 的小程序,有一個UDP 的server,而且有UDP的client。
然後執行server和client,然後用tcpmp將該埠的UDP數據報文抓取出來。
執行的過程是這樣的。
client向server發送"xiyou"
server向client應答"wangzhe"
client程序在主機example上運行(192.168.1.144)
server程序在主機linux上運行(192.168.1.101)
------------------------------------------------------------------------------------------------------------
2、UDP數據報文。
linux@linux:~$ sudo tcpmp -vvv -X udp port 7777
[sudo] password for linux:
tcpmp: listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
11:03:01.923227 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 48)
example.local.43521 > linux.7777: [udp sum ok] UDP, length 20
0x0000: 4500 0030 0000 4000 4011 b677 c0a8 0190 E..0..@[email protected]....
0x0010: c0a8 0165 aa01 1e61 001c 4c34 7869 796f ...e...a..L4xiyo
0x0020: 7500 0000 0000 0000 0000 0000 0000 0000 u...............
11:03:01.923343 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto UDP (17), length 48)
linux.7777 > example.local.43521: [bad udp cksum 6869!] UDP, length 20
0x0000: 4500 0030 0000 4000 4011 b677 c0a8 0165 E..0..@[email protected]
0x0010: c0a8 0190 1e61 aa01 001c 8473 7761 6e67 .....a.....swang
0x0020: 7a68 6500 0000 0000 0000 0000 0000 0000 zhe.............
由上面的報文可知,有兩個UDP數據報文。
第一個報文是example主機上的client向server發送數據。
4500 0030 0000 4000 4011 b677 c0a8 0190 c0a8 0165 這20個數據是IP首部。
aa01 1e61 001c 4c34 這8個位元組是UDP的首部。
7869 796f 7500 0000 0000 0000 0000 0000 0000 0000 這20個數據是我用sendto函數發送的
數據。
而將char req[20] = "xiyou" 的ASCII碼(16進制)就是:
78 69 79 6f 75 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
第二個報文是linux向主機example做出的應答。
4500 0030 0000 4000 4011 b677 c0a8 0165 c0a8 0190 這20個數據是IP首部。
1e61 aa01 001c 8473 這8個位元組是UDP首部。
7761 6e67 7a68 6500 0000 0000 0000 0000 0000 0000 這20個數據是應用層的數據。
而將char reply[20] = "wangzhe"的ASCII碼(16進制)就是:
77 61 6e 67 7a 68 65 0 0 0 0 0 0 0 0 0 0 0 0 0
由此看出,應用層的數據沒有夾雜其他的參數,全部是數據,均是字元的ASCII碼。
-----------------------------------------------------------------------
附帶網路程序:
udp_server.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <string.h>
int main(void)
{
struct sockaddr_in server,client;
int sockfd;
int cli_len = 0,n;
char req[20] = {0},reply[20] = {0};
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if (sockfd < 0) {
perror("socket error!\n");
exit(-1);
}
memset(&server,0,sizeof(struct sockaddr_in));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(7777);
if (bind(sockfd,(struct sockaddr *)&server,sizeof(server)) < 0) {
perror("bind error!\n");
exit(-1);
}
for (;;) {
cli_len = sizeof(struct sockaddr_in);
n = recvfrom(sockfd,req,20,0,(struct sockaddr *)&client,&cli_len);
if (n < 0) {
perror("recvfrom error!\n");
exit(-1);
}
printf("hello!\n");
strncpy(reply,"wangzhe",sizeof("wangzhe"));
if (sendto(sockfd,reply,20,0,(struct sockaddr *)&client,sizeof(client)) != 20) {
perror("sendto error!\n");
exit(-1);
}
}
return 0;
}
-----------------------------------------------------------------------------------------------------------
udp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <string.h>
int main(void)
{
int sockfd,n;
struct sockaddr_in server;
char req[20]={0},reply[20]={0};
sockfd = socket(AF_INET,SOCK_DGRAM,0);
if (sockfd < 0) {
perror("socket error!\n");
exit(-1);
}
memset(&server,0,sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("192.168.1.101");
server.sin_port = htons(7777);
strncpy(req,"xiyou",sizeof("xiyou"));
printf("sendto req to server:%s\n",req);
if (sendto(sockfd,req,20,0,(struct sockaddr *)&server,sizeof(server)) != 20) {
perror("sendto error!\n");
exit(-1);
}
if ((n = recvfrom(sockfd,reply,20,0,(struct sockaddr *)NULL,(int *)NULL)) < 0) {
perror("recvfrom error!\n");
exit(-1);
}
printf("recv reply from server :%s\n",reply);
exit(0);
}
--------------------------------------------------------------------------------------------------------