日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

UDP通信协议详解

發布時間:2023/11/27 生活经验 60 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UDP通信协议详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
中文名????????????????用戶數據報協議
英文名

User Datagram Protocol

基礎

IP數據包服務上增加一點功能

類別

傳輸層協議

特點

無連接、不可靠、快速傳輸

用途發送IP數據包

如右圖所所示為udp協議的基本信息

上圖就是UDP的數據報服務,sendto兩次發送的是單獨的兩個個體,接收端也就必須recvfrom兩次,所以UDP沒有粘包這種概念!

UDP(User Datagram Protocol)用戶數據報協議,非連接的協議,傳輸數據之前源端和終端不 建立連接,當它想傳送時就簡單地去抓取來自應用程序的數據,并盡可能快地把它扔到網絡上。 在發送端,UDP傳送數據的速度僅僅是受應用程序生成數據的速度、計算機的能力和傳輸帶寬 的限制;在接收端,UDP把每個消息段放在隊列中,應用程序每次從隊列中讀一個消息段。 相比TCP就是無需建立鏈接,結構簡單,無法保證正確性,容易丟包(菜鳥教程節選)。

UDP的不可靠性:

上面我們在表格中也說到了UDP協議它的特點就是無連接、不可靠、快速傳輸,先來說下它為什么不可靠,或者說它的不可靠可以為我們帶來什么別的方面的優化:

? ? ? ? 我們都知道TCP是流傳輸且它的特點是可靠(因為它需要確認應答、超時重傳這些操作),而在UDP傳輸則不需要哪些操作(TCP就像我們打電話,得知道對方的電話號碼,還得等對方接聽起來才可以就那些通話,但是UDP的話就像是發短信,只需要知道號碼就可以執行了,至于發送成功了沒這不重要,只要發出去就好了)

UDP的應用場景:

? ? ? ? 在我們視頻通話的時候用的就是UDP傳輸,假設A,B兩人再進行視頻通話,其中A網絡有點慢導致接收B的數據慢的很,但是B還是按照他那邊網速來勁傳輸,這樣就會導致兩人在視頻通話過程中丟包,但是因為這是UDP協議傳輸,所以無所謂啊,丟包就丟包,等A的網速好起來了再問下說你剛剛說了啥,B重新說一遍就好.

? ? ? ? 假設視頻通話使用的是TCP協議傳輸的話,在A網絡卡頓的時候就會造成接收緩沖區堆積,等A網絡好的時候看到的B相當于是幾分鐘之前的B,相當于看的B的錄屏,這在視頻通話中是根本不行的,所以TCP和UDP協議適用于不同的場景之下:TCP適合那種不允許丟包的網絡傳輸中,而UDP協議適用于那種允許丟包的網絡傳輸中(UDP效率很高)

大家不熟悉TCP的可以看下這篇:

TCP協議的服務器與客戶端的程序設計(代碼注釋超詳細)_神廚小福貴!的博客-CSDN博客

UDP客戶端和服務器端編程示例

服務器端

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>int main()
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);//創建套接字  SOCK_DGRAM這個為UDP數據報套接字assert(sockfd != -1);struct sockaddr_in saddr,caddr; //sockaddr_in在頭文件#include<netinet/in.h>或#include <arpa/inet.h>中定義,saddr代表服務器端地址  caddr代表客戶端地址memset(&saddr,0,sizeof(saddr));//saddr其實有四項成員,最后一項用來占位的,必須搞為0,索性我們開始直接給全部置為0,后面再來綁定ip和端口saddr.sin_family = AF_INET;//地址族,TCP/ipv4協議族saddr.sin_port = htons(6000);//端口為小端序列,htons轉換為網絡字節序,也是大端字節序(一般使用都是5000以上,5000以內一般都是特定使用的,比如你辦了個手機卡,你能用110這個號碼嘛,博客園因為110有特殊意義,一個道理)sadd r.sin_addr.s_addr = inet_addr("192.168.0.108");//自己本地的IP地址(終端ifconfig查詢自己的IP)//inet_addr將點分十進制轉換為午飯后整型int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//將sockfd和本地IP綁定//為什么要這個呢(struct sockaddr*)強轉呢,bind這個參數類型為struct sockaddr與sockaddr_in類型不一致,所以強轉assert(res != -1);// UDP協議傳輸中沒有監聽隊列這個東西while(1){int len = sizeof(caddr);char buff[128] = {0};recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len); //接收客戶端發的數據printf("buff = %s",buff);sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr)); //給客戶端發送okclose(c);}
}

客戶端:(和服務器端比起來就是,沒有那個bind\recvfrom和sendto的順序)

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>int main()
{int sockfd = socket(AF_INET,SOCK_DGRAM,0);//創建套接字assert(sockfd != -1);struct sockaddr_in saddr,caddr; //sockaddr_in在頭文件#include<netinet/in.h>或#include <arpa/inet.h>中定義,saddr代表服務器端地址  caddr代表客戶端地址memset(&saddr,0,sizeof(saddr));//saddr其實有四項成員,最后一項用來占位的,必須搞為0,索性我們開始直接給全部置為0,后面再來綁定ip和端口saddr.sin_family = AF_INET;//地址族,TCP/ipv4協議族saddr.sin_port = htons(6000);//端口為小端序列,htons轉換為網絡字節序,也是大端字節序(一般使用都是5000以上,5000以內一般都是特定使用的,比如你辦了個手機卡,你能用110這個號碼嘛,博客園因為110有特殊意義,一個道理)sadd r.sin_addr.s_addr = inet_addr("192.168.0.108");//自己本地的IP地址(終端ifconfig查詢自己的IP)//inet_addr將點分十進制轉換為午飯后整型while(1){char budd[128] = {0};fgets(buff,128,stdin);if(strncmp(buff,"end",3) == 0){break;}sendto(sockfd,buff,strlen(buff)-1,0,(struct sockaddr*)&saddr,sizeof(saddr));//TCP中參數只需要寫到0那塊  主要是TCP中可以通過描述符查詢到底層端口memset(buff,0,128);int len = sizeof(saddr);recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len);printf("buff = %s \n",buff);}close(sockfd);
}

不可靠的解決?

我們都知道UDP傳輸不可靠,那么如何解決呢?有種笨辦法就是在每次傳輸完數據之后必須接收recvfrom一個數據才可以得以繼續進行,否則就堵塞在revcfrom那塊,那么這種方法不就和TCP一樣了嗎(并且可能自己在應用層實現的應答確認機制沒有TCP中的應答確認機制效率高而將它弄成四不像),且丟失了UDP的最大特點-------效率.(最后這段話完全是自己的想法,不知道正確與否,如有不恰當之處,歡迎各位指出)

"好好學習,趁著還來得及!!!"

總結

以上是生活随笔為你收集整理的UDP通信协议详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。