網路通訊之TCP UDP

2022-06-25 18:48:12 字數 3905 閱讀 5536

1、udp乙個socket接收緩衝區的預設值

cat /proc/sys/net/core/rmem_default
~$ 212992,單位byte,=208kb

3、每個udp socket都有乙個接收緩衝區,沒有傳送緩衝區,從概念上來說就是只要有資料就發,不管對方是否可以正確接收,所以不緩衝,不需要傳送緩衝區。

udp:當套接字接收緩衝區滿時,新來的資料報無法進入接收緩衝區,此資料報就被丟棄。udp是沒有流量控制的,快的傳送者可以很容易的湮沒慢的接收者,導致接收方的udp 丟棄新來的資料報。

4、概念

實際上在同乙個網段,或者在訊號很好的區域網,udp實際上是非常可靠的。如沒有丟包幷包的按順序依次到達(這個幾乎是短區域網的常態),並不需要重新傳輸包,所以tcp的所有應答和等待只會浪費時間,增加網路延時。

5、單播 

一對一通訊。通常我們討論的udp的程式都是一對一的單播程式。

6、廣播

乙個主機對整個區域網上所有主機上的資料通訊。

廣播udp與單播udp的區別就是ip位址不同,廣播使用廣播位址255.255.255.255,將訊息傳送到在同一廣播網路上的每個主機。值得強調的是:本地廣播資訊是不會被路由器**。當然這是十分容易理解的,因為如果路由器**了廣播資訊,那麼勢必會引起網路癱瘓。這也是為什麼ip協議的設計者故意沒有定義網際網路範圍的廣播機制。

廣播位址通常用於在網路遊戲中處於同一本地網路的玩家之間交流狀態資訊等。

其實廣播顧名思義,就是想區域網內所有的人說話,但是廣播還是要指明接收者的埠號的,因為不可能接受者的所有埠都來收聽廣播。

7、多播(multicasting)

單播用於兩個主機之間的端對端通訊,廣播用於乙個主機對整個區域網上所有主機上的資料通訊。單播和廣播是兩個極端,要麼對乙個主機進行通訊,要麼對整個區域網上的主機進行通訊。實際情況下,經常需要對一組特定的主機進行通訊,而不是整個區域網上的所有主機,這就是多播的用途。

這裡可以簡化下tcp/ip/udp的相關討論,預設我們知道ip(udp和tcp一樣)可以把資料報在乙個網路中發到另乙個裝置。更準確點就是ip把資料報從乙個ip位址發到另乙個ip位址。多播的決竅就是在同一時間把乙個資料報傳送到多個裝置,可以把乙個特定的ip位址指定為多播位址,並同時傳送到多個裝置。

ip多播首先要知道的是只有udp有多播,沒有tcp多播這樣的東西,為什麼呢?多播的重點是高效的把同乙個包盡可能多的傳送到不同的,甚至可能是未知的裝置。但是tcp連線可能要求丟包重發或者延時或重組順序,這些操作可能非常消耗資源,不適於許多使用多播的應用場景。(同時多播不知道發出的包是不是已經到達,這個也導致不能使用tcp)。

基於tcp socket程式設計,假設tcp最多一次只能傳送1k byte的資料,伺服器端程式首先要將300k資料按照順序砍成300塊 (segment),按照從頭到尾編號,1-300,然後呼叫send()函式300次,嚴格按照時間順序,第一次呼叫發編號1,第二次呼叫發編號2,…第三百次呼叫發編號300,這個不複雜,只要編寫乙個迴圈程式(300次)即可,只要每次呼叫的返回值都ok,應用程式的任務就算完成了。

以上的編號1-300就是tcp segment編號,那位元組流的編號呢,就是 1,300000,其中 1-1000 位元組被編在1號tcp segment,1001-2000位元組編在2號segment,以此類推。

tcp不關心本地send()給自己的內容是啥(反正都是位元組),只關心時序,先發給自己的肯定先編號,後發的後編號,tcp本身只保證傳輸的順序,至於在伺服器端本地、客戶端本地的順序則由receive()/ send()時序來保證!

問題的關鍵在於tcp是有緩衝區,作為對比,udp面向報文段是沒有緩衝區的。

tcp傳送報文時,是將應用層資料寫入tcp緩衝區中,然後由tcp協議來控制傳送這裡面的資料,而傳送的狀態是按位元組流的方式傳送的,跟應用層寫下來的報文長度沒有任何關係,所以說是流。

作為對比的udp,它沒有緩衝區,應用層寫的報文資料會直接加包頭交給網路層,由網路層負責分片,所以是面向報文段的。

sudo tcpdump -i enp0s25 udp port 2000 

實測,在未經更改的ubuntu上,udp的sendto函式,一次最大傳送資料量為65507byte。超過這個大小,傳送會失敗,sendto()函式返回-1。

和理論計算結果一致,udp協議資料報最大長度 = 65535 - 20(ip頭)-8(udp頭) = 65507

1、正常情況下,一般設定接收buf大於傳送buf,在阻塞模式下,udp的通訊是以資料報作為界限的,即使server端的緩衝區再大也要按照client發包的次數來多次接收資料報,server只能一次一次的接收,client傳送多少次,server就需接收多少次,即客戶端分幾次傳送過來,服務端就必須按幾次接收。

2、接收buf  < 傳送buf,接收方實際情況如何?

server端呼叫recvfrom()函式按包接收,接收buf能夠接收到length(buf)長度的有效資料,不能夠迴圈接收,這個包剩餘的資料會被丟棄,如下圖:傳送方傳送兩個位元組資料,第乙個位元組儲存9,第二個位元組儲存2。當接收快取設定1byte時,接收到的資料永遠是9,第二個位元組被丟棄。

傳送方一次傳送20m資料,接受快取4k;

1、接收buf  < 傳送buf,接收方實際情況如何?

tcp傳輸的實質,是流式傳輸,就是不管你傳送的時候是一次傳送多少,tcp的底層處理,都是乙個位元組乙個位元組按流傳送的。

傳送端: 可以正常傳送出去;

接收端:能接收到4k資料, 可迴圈接收;

下圖測試傳送buf =4,接收buf =1。可以看出接收方迴圈接收了每個資料。

接收函式recv()、recvfrom(),如果不進行設定,預設都是阻塞模式,即接收不到訊息不返回。

而且我們經常將接收函式放在乙個子執行緒中迴圈接收,如果寫while(1)死迴圈,就會造成ctrl + c結束不了程式。處理方法有如下幾種:

1、fake乙個假資料報給這個相應的埠,通過長度/內容判斷是否退出執行緒。

2、在呼叫recvfrom前,將recvfrom設定成非阻塞模式,這個方法容易導致cpu佔用率大幅上公升。

3、使用select/epoll來接收。

4、在呼叫recvfrom前,將recvfrom設定乙個超時時間,然後使用signal函式處理ctrl+c訊號,從而改變標誌位

#include #include static int keeprunning = 1; //定義為全域性變數

void sig_handler( int sig )

}signal(sigint, sig_handler );

//子執行緒

·····

//設定接收超時

struct timeval tv_out;

tv_out.tv_sec = 1;//等待1秒

tv_out.tv_usec = 0;

setsockopt(fd,sol_socket,so_rcvtimeo,&tv_out, sizeof(tv_out));

while(keeprunning)

·······

網路通訊TCP UDP

這個學期幾乎都在學網路通訊的內容。基於tcp協議的通訊,通過乙個socket來連線伺服器和客戶機之間的通訊。要求雙方必須要連線之後,才能傳送和接受訊息。如果有一方斷開連線,則通訊終止。這保證了訊息傳輸的準確性,不會發生訊息的丟失,但是通訊的速度有所降低。基於udp協議的通訊,不要求伺服器和客戶機連線...

網路通訊TCP UDP 學習筆記

參考文獻 35 張 被問千百遍的 tcp 三次握手和四次揮手面試題 一 網路通訊的基本概念 1 tcp和udp的區別 tcp transmission control protocol 傳輸控制協議,面向連線的服務 類似打 安全 可 靠 三次握手 響應 重傳 四次揮手 速度相對較慢,一般應用在對安全...

網路通訊之校驗

這是乙個可選的選項,並不是所有的系統都對udp資料報加以檢驗和資料 相對tcp協議的必須來說 但是rfc中標準要求,傳送端應該計算檢驗和。udp檢驗和 覆蓋udp協議頭和資料,這和ip的檢驗和是不同的,ip協議的檢驗和只是覆蓋ip資料頭,並不覆蓋所有的資料。tcp校驗 首部和資料的校驗和 udp校驗...