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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

UDP通信协议详解

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

User Datagram Protocol

基礎(chǔ)

IP數(shù)據(jù)包服務(wù)上增加一點功能

類別

傳輸層協(xié)議

特點

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

用途發(fā)送IP數(shù)據(jù)包

如右圖所所示為udp協(xié)議的基本信息

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

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

UDP的不可靠性:

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

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

UDP的應(yīng)用場景:

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

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

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

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

UDP客戶端和服務(wù)器端編程示例

服務(wù)器端

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

客戶端:(和服務(wù)器端比起來就是,沒有那個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);//創(chuàng)建套接字assert(sockfd != -1);struct sockaddr_in saddr,caddr; //sockaddr_in在頭文件#include<netinet/in.h>或#include <arpa/inet.h>中定義,saddr代表服務(wù)器端地址  caddr代表客戶端地址memset(&saddr,0,sizeof(saddr));//saddr其實有四項成員,最后一項用來占位的,必須搞為0,索性我們開始直接給全部置為0,后面再來綁定ip和端口saddr.sin_family = AF_INET;//地址族,TCP/ipv4協(xié)議族saddr.sin_port = htons(6000);//端口為小端序列,htons轉(zhuǎn)換為網(wǎng)絡(luò)字節(jié)序,也是大端字節(jié)序(一般使用都是5000以上,5000以內(nèi)一般都是特定使用的,比如你辦了個手機卡,你能用110這個號碼嘛,博客園因為110有特殊意義,一個道理)sadd r.sin_addr.s_addr = inet_addr("192.168.0.108");//自己本地的IP地址(終端ifconfig查詢自己的IP)//inet_addr將點分十進(jìn)制轉(zhuǎn)換為午飯后整型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中參數(shù)只需要寫到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傳輸不可靠,那么如何解決呢?有種笨辦法就是在每次傳輸完數(shù)據(jù)之后必須接收recvfrom一個數(shù)據(jù)才可以得以繼續(xù)進(jìn)行,否則就堵塞在revcfrom那塊,那么這種方法不就和TCP一樣了嗎(并且可能自己在應(yīng)用層實現(xiàn)的應(yīng)答確認(rèn)機制沒有TCP中的應(yīng)答確認(rèn)機制效率高而將它弄成四不像),且丟失了UDP的最大特點-------效率.(最后這段話完全是自己的想法,不知道正確與否,如有不恰當(dāng)之處,歡迎各位指出)

"好好學(xué)習(xí),趁著還來得及!!!"

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。