Socket程式設計實踐 12 UDP程式設計基礎

2022-04-29 19:18:09 字數 2732 閱讀 5854

無連線,面向資料報(基於訊息,不會粘包)的資料傳輸服務;

不可靠(可能會丟包, 亂序, 重複), 但因此一般情況下udp更加高效;

udp客戶/伺服器模型

/**實踐: 實現乙個基於udp的echo回聲server/client**/

//server端**

void echoserver(int sockfd);

int main()

void echoserver(int sockfd)

cout << buf ;

if (sendto(sockfd, buf, recvbytes, 0,

(const struct sockaddr *)&clientaddr, addrlen) == -1)

err_exit("sendto error");}}

/**client端****/

void echoclient(int sockfd);

int main()

void echoclient(int sockfd)

; while (fgets(buf, sizeof(buf), stdin) != null)

cout << buf ;

memset(buf, 0, sizeof(buf));}}

實踐解析:編譯執行server,在兩個終端裡各開乙個client與server互動,可以看到server具有併發服務的能力。用關閉server,然後再執行server,此時client還能和server聯絡上。和前面tcp程式的執行結果相比較,我們可以體會無連線的含義。udp 協議來說,server與client 的界限更模糊了,只要知道對等方位址(ip和port) 都可以主動發資料。

1.udp報文可能會丟失(超時重傳)、重複、亂序(維護乙個序號)

2.udp缺乏流量控制

:當緩衝區寫滿以後,由於udp沒有流量控制機制,因此會覆蓋緩衝區。

3.udp協議資料報文截斷:如果對端傳送的udp資料報大於本地接收緩衝區,報文可能被截斷,後面的部分會丟失(而不是像我們想象的下一次能夠接收到)。

4.recvfrom可以返回0,並不代表連線關閉,因為udp是無連線的, 代表傳送端沒有傳送任何資料[sendto可以傳送資料0包(只含有udp+ip首部40b)]。

5.icmp非同步錯誤

觀察現象:使用上例,關閉udp服務端,啟動客戶端,從鍵盤接受資料後,再傳送資料。如果recvfrom中flags標誌為0, 且client端沒有呼叫connect的情況下, udp客戶端阻塞在recvfrom位置(見測試**3);

說明:1)udp傳送報文的時,只把資料copy到傳送緩衝區。在伺服器沒有起來的情況下,可以傳送成功。

2)所謂icmp非同步錯誤是指:傳送的報文的時候,沒有錯誤,接受報文recvfrom的時候,**到icmp應答.

3)非同步的錯誤,無法返回未連線的套接字, 因此如果上例我們呼叫了connect, 是可以收到該非同步icmp報文的;

6.udp呼叫connect

1)udp呼叫connet,並沒有三次握手,只是維護了乙個(和對等方的)狀態資訊, 因此我們可以看到即使server沒有開啟, client端的connect依然還可以正確返回的!(測試**如測試**2)

2)一但呼叫connect, 傳送可以使用send/write, 接收可以使用recv/read函式(見測試**3)

7.udp外出介面的確定:

假設客戶端有多個ip位址,由connect /sendto 函式提供的遠端位址的引數,系統會選擇乙個合適的出口,比如server的ip是192.168.2.10, 而客戶端現在的ip有 192.168.1.32 和 192.168.2.75 那麼會自動選擇192.168.2.75 這個ip出去。

/**測試1: 測試注意點3, udp報文截斷, recvfrom返回-1, errno值為eagain**/

int main()

else

cout << "char = " << ch << ", recvbytes = " << recvbytes << endl;}}

/**測試2:將client端echoclient函式的**改造如下, 注意是在server端尚未開啟時執行該程式**/

void echoclient(int sockfd)

; while (fgets(buf, sizeof(buf), stdin) != null)

}

/**測試3: client端在呼叫connect之後呼叫send, 而不是send**/

void echoclient(int sockfd)

; while (fgets(buf, sizeof(buf), stdin) != null)

}

UDP之Socket程式設計

建立服務端socket物件 datagramsocket datagramsocket server newdatagramsocket 12331 建立接受資料報的容器 byte bytes newbyte 1024 datagrampacket packet newdatagrampacket ...

socket程式設計實踐

socket程式設計 1 函式說明。socket 程式設計的基本函式有 socket bind listen accept send sendto recv 以及 recvfrom 等,其中根據客戶端還是服務端,或者根據使用 tcp 協議還是 udp 協議,這些函式的呼叫流程都有所區別,這裡先對每個...

socket程式設計實踐

建立連線 1.1socket 非常類似於open函式,用來開啟乙個網路連線,如果成功則返回乙個網路檔案描述符 int型別 之後我們操作這個網路連線都通過這個網路檔案描述符 1.2bind繫結的意思 好比是ioctl 1.3listen監聽 1.4connect連線 客戶端 傳送和接收 2.1 sen...