0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

UDP網(wǎng)絡(luò)編程

嵌入式技術(shù) ? 來(lái)源:嵌入式技術(shù) ? 作者:嵌入式技術(shù) ? 2022-08-26 20:58 ? 次閱讀

UDP網(wǎng)絡(luò)編程

1.UDP協(xié)議簡(jiǎn)介

UDP協(xié)議采用無(wú)連接的方式,不管發(fā)送的數(shù)據(jù)包是否到達(dá)目的主機(jī),數(shù)據(jù)包是否出錯(cuò)。收到數(shù)據(jù)包的主機(jī)也不會(huì)告訴發(fā)送方是否正確收到了數(shù)據(jù),它的可靠性是由上層協(xié)議來(lái)保障的。

UDP 是User Datagram Protocol的簡(jiǎn)稱, 中文名是用戶數(shù)據(jù)報(bào)協(xié)議,是OSI(Open System Interconnection,開(kāi)放式系統(tǒng)互聯(lián)) 參考模型中一種無(wú)連接的傳輸層協(xié)議,提供面向事務(wù)的簡(jiǎn)單不可靠信息傳送服務(wù),IETF RFC 768 [1] 是UDP的正式規(guī)范。UDP在IP報(bào)文的協(xié)議號(hào)是17。

UDP是無(wú)連接的服務(wù)。在無(wú)連接服務(wù)的情況下,兩個(gè)實(shí)體之間的通信不需先建立好一個(gè)連接,因此其下層的有關(guān)資源不需要事先進(jìn)行預(yù)定保留。這些資源將在數(shù)據(jù)傳輸時(shí)動(dòng)態(tài)地進(jìn)行分配。無(wú)連接服務(wù)的另一特征就是它不需要通信的兩個(gè)實(shí)體同時(shí)是活躍的(即處于激活態(tài))。當(dāng)發(fā)送端的實(shí)體正在進(jìn)行發(fā)送時(shí),它才必須是活躍的。優(yōu)點(diǎn)是靈活方便和比較迅速,但不能防止報(bào)文的丟失、重復(fù)或失序,特別適合于傳送少量零星的報(bào)文。

UDP報(bào)文沒(méi)有可靠性保證、順序保證和流量控制字段等,可靠性較差。但是正因?yàn)閁DP協(xié)議的控制選項(xiàng)較少,在數(shù)據(jù)傳輸過(guò)程中延遲小、數(shù)據(jù)傳輸效率高,適合對(duì)可靠性要求不高的應(yīng)用程序,或者可以保障可靠性的應(yīng)用程序,如DNS、TFTP、SNMP等。

pYYBAGMIw3iAOAaBAAHTUyEWM6c268.png#pic_center

? UDP和TCP協(xié)議的主要區(qū)別是兩者在如何實(shí)現(xiàn)信息的可靠傳遞方面不同。TCP協(xié)議中包含了專門(mén)的傳遞保證機(jī)制,當(dāng)數(shù)據(jù)接收方收到發(fā)送方傳來(lái)的信息時(shí),會(huì)自動(dòng)向發(fā)送方發(fā)出確認(rèn)消息;發(fā)送方只有在接收到該確認(rèn)消息之后才繼續(xù)傳送其它信息,否則將一直等待直到收到確認(rèn)信息為止。與TCP不同,UDP協(xié)議并不提供數(shù)據(jù)傳送的保證機(jī)制。如果在從發(fā)送方到接收方的傳遞過(guò)程中出現(xiàn)數(shù)據(jù)包的丟失,協(xié)議本身并不能做出任何檢測(cè)或提示。因此,通常人們把UDP協(xié)議稱為不可靠的傳輸協(xié)議。

2.UDP通訊流程

poYBAGMIw3iASmZUAADXwfD9_Ss735.png#pic_center

一般在UDP通訊中我們不太區(qū)分服務(wù)端和客戶端,由于UDP通訊不需要建立連接,因此UDP通訊中主要稱為發(fā)送方和接收方。

  • 發(fā)送方創(chuàng)建過(guò)程:

1.創(chuàng)建網(wǎng)絡(luò)套接字socket
2.發(fā)送數(shù)據(jù)sendto

  • 接收方創(chuàng)建過(guò)程:

1.創(chuàng)建網(wǎng)絡(luò)套接字socket
2.綁定端口號(hào)
3.接收數(shù)據(jù)recvfrom

2.1 函數(shù)接口

#include 
#include 
發(fā)送數(shù)據(jù)
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,const struct sockaddr *dest_addr, socklen_t addrlen);
形參: sockfd --套接字,socket函數(shù)返回值
???buf – 要發(fā)送是內(nèi)容
???len --要發(fā)送的數(shù)據(jù)長(zhǎng)度
???flags --一般填0即可
???dest_addr、addrlen —和connect后兩個(gè)參數(shù)類似
???dest_addr —對(duì)方網(wǎng)絡(luò)結(jié)構(gòu)體信息
??? addrlen --dest_addr結(jié)構(gòu)體大小
返回值: 成功返回發(fā)送字節(jié)數(shù),失敗返回-1
接收數(shù)據(jù)
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr, socklen_t *addrlen);
形參: sockfd --套接字,socket函數(shù)返回值
??? buf – 讀取內(nèi)容存放地址
??? len --要讀取的數(shù)據(jù)長(zhǎng)度
??? flags --一般填0即可
??? src_addr、addrlen —和accept后兩個(gè)參數(shù)類似
??? src_addr —保存發(fā)送者的IP和端口號(hào)
??? addrlen —src_addr結(jié)構(gòu)體大小
返回值: 成功返回讀取到的字節(jié)數(shù),失敗返回-1;
  • 發(fā)送方示例
#include           /* See NOTES */
#include 
#include 
#include 
#include  /* superset of previous */
#include 
#include 
#include 
int main(int argc,char *argv[])
{
	if(argc!=3)
	{
		printf("格式:./a.out <端口號(hào)> \n");
		return 0;
	}
	int sockfd=socket(AF_INET,SOCK_DGRAM,0);	
	if(sockfd==-1)
	{
		printf("創(chuàng)建網(wǎng)絡(luò)套接字失敗\n");
		return 0;
	}
	struct sockaddr_in s_addr=
	{
		.sin_family=AF_INET,
		.sin_port=htons(atoi(argv[1])),
		.sin_addr.s_addr=inet_addr(argv[2]),//本地所有IP
	};
	char buff[]="UDP發(fā)送數(shù)據(jù)測(cè)試!";
	ssize_t size;
	while(1)
	{
		size=sendto(sockfd,buff,sizeof(buff),0,( const struct sockaddr * )&s_addr,sizeof(s_addr));
		printf("發(fā)送數(shù)據(jù)成功size=%ld\n",size);
		sleep(1);
	}
}
地址>
  • 接收方示例
#include 
#include           /* See NOTES */
#include 
#include 
#include  /* superset of previous */
#include 
#include 
#include 
int main(int argc,char *argv[])
{
	if(argc!=2)
	{
		printf("./a.out <端口號(hào)>\n");
		return 0;
	}
	/*1.創(chuàng)建網(wǎng)絡(luò)套接字*/
	int sockfd=socket(AF_INET,SOCK_DGRAM, 0);
	if(sockfd==-1)
	{
		printf("創(chuàng)建UDP網(wǎng)絡(luò)套接字失敗\n");
		return 0;
	}
	/*2.綁定端口號(hào)*/
	struct sockaddr_in addr=
	{
		.sin_family=AF_INET,
		.sin_port=htons(atoi(argv[1])),//發(fā)送的端口號(hào)
		.sin_addr.s_addr=INADDR_ANY,//本地所有IP
	};
	if(bind(sockfd,(const struct sockaddr *)&addr,sizeof(struct sockaddr)))
	{
		printf("綁定端口號(hào)失敗\n");
		return 0;
	}
	/*開(kāi)始接收數(shù)據(jù)*/
	char buff[256];
	struct sockaddr_in c_addr;
	socklen_t addrlen=sizeof(struct sockaddr_in);
	ssize_t size;
	while(1)
	{
		size=recvfrom(sockfd,buff,sizeof(buff)-1,0,(struct sockaddr *)&c_addr,&addrlen);
		if(size<=0)
		{
			printf("接收數(shù)據(jù)失敗\n");
			continue;
		}
		buff[size]='\0';
		printf("[%s:%d] %s,len=%ld byte\n",inet_ntoa(c_addr.sin_addr),ntohs(c_addr.sin_port),buff,size);
	}
	close(sockfd);
}
pYYBAGMIw3mAUCmxAALajOIQxME649.png#pic_center

2.2 設(shè)置UDP廣播特性

??默認(rèn)情況下UDP通訊是不支持廣播特性,需要廣播特性則需要設(shè)置UDP套接字屬性。

//設(shè)置該套接字為廣播類型,
	int nb = 0;
	nb = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt));
	if(nb == -1)
	{
		printf("設(shè)置廣播類型錯(cuò)誤.\n");
	}
  • 廣播發(fā)送方示例
#include           /* See NOTES */
#include 
#include 
#include 
#include  /* superset of previous */
#include 
#include 
#include 
int main(int argc,char *argv[])
{
	if(argc!=3)
	{
		printf("格式:./a.out <端口號(hào)> \n");
		return 0;
	}
	int sockfd=socket(AF_INET,SOCK_DGRAM,0);	
	if(sockfd==-1)
	{
		printf("創(chuàng)建網(wǎng)絡(luò)套接字失敗\n");
		return 0;
	}
	//設(shè)置該套接字為廣播類型,
	const int opt = 1;
	int nb = 0;
	nb = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char *)&opt, sizeof(opt));
	if(nb == -1)
	{
		printf("設(shè)置廣播類型錯(cuò)誤.\n");
	}
	struct sockaddr_in s_addr=
	{
		.sin_family=AF_INET,
		.sin_port=htons(atoi(argv[1])),
		.sin_addr.s_addr=inet_addr(argv[2]),//本地所有IP
	};
	char buff[]="UDP send data test,hello,world!";
	ssize_t size;
	while(1)
	{
		size=sendto(sockfd,buff,sizeof(buff),0,( const struct sockaddr * )&s_addr,sizeof(s_addr));
		printf("發(fā)送數(shù)據(jù)成功size=%ld\n",size);
		sleep(1);
	}
}
地址>
poYBAGMIw3qAGM7nAAWskBeT12A100.png#pic_center

審核編輯 黃昊宇
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 廣播
    +關(guān)注

    關(guān)注

    1

    文章

    306

    瀏覽量

    23065
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3616

    瀏覽量

    93763
  • UDP
    UDP
    +關(guān)注

    關(guān)注

    0

    文章

    325

    瀏覽量

    33957
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    626.【day27】23 尚硅谷 Java語(yǔ)言高級(jí) UDP網(wǎng)絡(luò)編程舉例 #硬聲創(chuàng)作季

    編程項(xiàng)目開(kāi)發(fā)
    充八萬(wàn)
    發(fā)布于 :2023年07月19日 08:16:33

    基于IPv6的Winsock網(wǎng)絡(luò)編程

    {u_int8_t __u6_addr8[16];}2 程序源代碼UDP協(xié)議(User Datagram Protocol),即用戶數(shù)據(jù)報(bào)協(xié)議,是定義用來(lái)在互連網(wǎng)絡(luò)環(huán)境中提供包交換的計(jì)算機(jī)通信的協(xié)議。UDP
    發(fā)表于 05-08 06:14

    嵌入式Linux系統(tǒng)開(kāi)發(fā)學(xué)習(xí)路線

    Linux網(wǎng)絡(luò)發(fā)展、TCPIP協(xié)議、socket編程、TCP網(wǎng)絡(luò)編程、UDP網(wǎng)絡(luò)
    發(fā)表于 09-21 10:09

    【Rico Board試用體驗(yàn)】嵌入式網(wǎng)絡(luò)編程實(shí)現(xiàn)與測(cè)試

    和服務(wù)器之間建立一個(gè)連接,且沒(méi)有超時(shí)重發(fā)等機(jī)制,故而傳輸速度很快。 這里將介紹常用的UDP網(wǎng)絡(luò)編程。3 UDP編程介紹
    發(fā)表于 12-11 22:52

    Linux基礎(chǔ)

    過(guò)程中使用非常廣泛,通過(guò)Linux網(wǎng)絡(luò)發(fā)展、TCP/IP協(xié)議、socket編程、TCP網(wǎng)絡(luò)編程、UDP網(wǎng)
    發(fā)表于 08-03 09:46

    python黑客操作:遠(yuǎn)程開(kāi)機(jī)和關(guān)機(jī)

    FF FF”連續(xù)6個(gè)“FF”,后面跟著MAC地址信息,一旦網(wǎng)卡檢測(cè)到數(shù)據(jù)包的內(nèi)容,就會(huì)喚醒目標(biāo)計(jì)算機(jī)。讓我們看看如何編寫(xiě)代碼。該代碼涉及UDP網(wǎng)絡(luò)編程,稍后將專門(mén)編寫(xiě)。此功能只需要輸入目標(biāo)計(jì)算機(jī)
    發(fā)表于 01-19 20:22

    鴻蒙HarmonyOS and 無(wú)人機(jī)

    利用鴻蒙Hispark WIFI IOT 套件控制大疆TELLO 無(wú)人機(jī)第一步:查看無(wú)人機(jī)通信協(xié)議:第二步:結(jié)合UDP網(wǎng)絡(luò)編程--UDP demo 寫(xiě)入無(wú)人機(jī)的wifi名稱,密碼,ip
    發(fā)表于 11-20 09:16

    鴻蒙HarmonyOS 結(jié)合 大疆Tello TT無(wú)人機(jī) 開(kāi)啟智能家居物聯(lián)網(wǎng)新模式

    /RoboMaster%20TT/Tello_SDK_3.0_User_Guide.pdf)第二步:結(jié)合鴻蒙UDP網(wǎng)絡(luò)編程相關(guān)部分寫(xiě)入無(wú)人機(jī)的wifi名稱,密碼,ip地址,端口
    發(fā)表于 12-22 14:32

    迅為4412開(kāi)發(fā)板Qt網(wǎng)絡(luò)編程-UDP實(shí)現(xiàn)服務(wù)器和客戶端

    UDP 協(xié)議是開(kāi)放式,無(wú)連接,不可靠的傳輸層通信協(xié)議,但它收發(fā)數(shù)據(jù)的速度相對(duì)于 TCP 快很多,常用在傳輸音視頻等數(shù)據(jù)量非常大的場(chǎng)合。udp 網(wǎng)絡(luò)編程只需要使用一個(gè)類 QUdpSock
    發(fā)表于 05-13 10:56

    基于UDP協(xié)議的Socket網(wǎng)絡(luò)編程模式的實(shí)現(xiàn)

    傳輸層進(jìn)行網(wǎng)絡(luò)通信編程的接口是Socket&它是通用的開(kāi)發(fā)網(wǎng)絡(luò)通信程序標(biāo)準(zhǔn)) 本文介紹了基于UDP協(xié)議Socket編程機(jī)制和原理& 提出了在
    發(fā)表于 09-09 15:10 ?42次下載

    Linux下的UDP協(xié)議編程

    Linux下的UDP協(xié)議編程 介紹UDP協(xié)議,并提供一個(gè)適用于客戶端和服務(wù)器端的實(shí)例子程序?! £P(guān)鍵詞:Linux;UDP協(xié)議;TCP/IP協(xié)議;程序設(shè)計(jì)
    發(fā)表于 10-16 22:22 ?3977次閱讀
    Linux下的<b class='flag-5'>UDP</b>協(xié)議<b class='flag-5'>編程</b>

    Linux開(kāi)發(fā)_網(wǎng)絡(luò)編程、網(wǎng)絡(luò)通信介紹

    介紹Linux網(wǎng)絡(luò)編程: TCP網(wǎng)絡(luò)編程UDP網(wǎng)絡(luò)編程
    的頭像 發(fā)表于 09-17 15:46 ?1289次閱讀
    Linux開(kāi)發(fā)_<b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>編程</b>、<b class='flag-5'>網(wǎng)絡(luò)</b>通信介紹

    TCP/UDP網(wǎng)絡(luò)編程的基礎(chǔ)知識(shí)合集1

    本文主要記錄TCP/UDP網(wǎng)絡(luò)編程的基礎(chǔ)知識(shí),采用TCP/UDP實(shí)現(xiàn)宿主機(jī)和目標(biāo)機(jī)之間的網(wǎng)絡(luò)通信。
    的頭像 發(fā)表于 05-18 17:31 ?713次閱讀

    TCP/UDP網(wǎng)絡(luò)編程的基礎(chǔ)知識(shí)合集2

    本文主要記錄TCP/UDP網(wǎng)絡(luò)編程的基礎(chǔ)知識(shí),采用TCP/UDP實(shí)現(xiàn)宿主機(jī)和目標(biāo)機(jī)之間的網(wǎng)絡(luò)通信。
    的頭像 發(fā)表于 05-18 17:31 ?654次閱讀

    TCP/UDP網(wǎng)絡(luò)編程的基礎(chǔ)知識(shí)合集3

    本文主要記錄TCP/UDP網(wǎng)絡(luò)編程的基礎(chǔ)知識(shí),采用TCP/UDP實(shí)現(xiàn)宿主機(jī)和目標(biāo)機(jī)之間的網(wǎng)絡(luò)通信。
    的頭像 發(fā)表于 05-18 17:31 ?797次閱讀
    TCP/<b class='flag-5'>UDP</b><b class='flag-5'>網(wǎng)絡(luò)</b><b class='flag-5'>編程</b>的基礎(chǔ)知識(shí)合集3