{
\"code\": 200,
\"title\": \"\",
\"content\": \"UDP是UserDatagramProtocol的簡稱,中文名是用戶數據包協議,是OSI參考模型中一種無連接的傳輸層協議,提供麵向事務的簡單不可靠資訊傳送服務。它是IETFRFC768是UDP的正式規範。\\n\\nUDP是OSI參考模型中一種無連接的傳輸層協議,提供麵向事務的簡單不可靠資訊傳送服務。UDP協議基本上是IP協議與上層協議的介麵。UDP協議適用分彆運行在同一台設備上的多個應用程式。\\n\\n簡介\\n\\nUDP協議的全稱是用戶數據包協議,在網絡中它與TCP協議一樣用於處理\\n\\nUDP\\n\\nUDP數據包,是一種無連接的協議。在OSI模型中,在第四層——傳輸層,\\n\\n處於IP協議的上一層。UDP有不提供數據包分組、組裝和不能對數據包進行排序的缺點,也就是說,當報文發送之後,是無法得知其是否安全完整到達的。UDP用來支援那些需要在計算機之間傳輸數據的網絡應用。包括網絡視頻會議係統在內的眾多的客戶\\/服務器模式的網絡應用都需要使用UDP協議。UDP協議從問世至今已經被使用了很多年,雖然其最初的光彩已經被一些類似協議所掩蓋,但是即使是在今天,UDP仍然不失為一項非常實用和可行的網絡傳輸層協議。\\n\\n與所熟知的TCP(傳輸控製協議)協議一樣,UDP協議直接位於IP(網際協議)協議的頂層。根據OSI(開放係統互連)參考模型,UDP和TCP都屬於傳輸層協議。\\n\\nUDP協議的主要作用是將網絡數據流量壓縮成數據包的形式。一個典型的數據包就是一個二進製數據的傳輸單位。每一個數據包的前8個字節用來包含報頭資訊,剩餘字節則用來包含具體的傳輸數據。\\n\\n使用UDP\\n\\n在選擇使用協議的時候,選擇UDP必須要謹慎。在網絡質量令人不十分滿意的環境下,UDP協議數據包丟失會比較嚴重。但是由於UDP的特性:它不屬於連接型協議,因而具有資源消耗小,處理速度快的優點,所以通常音頻、視頻和普通數據在傳送時使用UDP較多,因為它們即使偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。比如我們聊天用的ICQ和QQ就是使用的UDP協議。\\n\\nUDP報頭\\n\\nUDP\\n\\nUDP報頭由4個域組成,其中每個域各占用2個字節,具體如下:\\n\\nUDP源\\n\\n號\\n\\n目標號\\n\\n數據報長度\\n\\n校驗值\\n\\nUDP協議使用號為不同的應用保留其各自的數據傳輸通道。UDP和TCP協議正是采用這一機製實現對同一時刻內多項應用同時發送和接收數據的支援。數據發送一方(可以是客戶端或服務器端)將UDP數據報通過源發送出去,而數據接收一方則通過目標接收數據。有的網絡應用隻能使用預先為其預留或註冊的靜態;而另外一些網絡應用則可以使用未被註冊的動態。因為UDP報頭使用兩個字節存放號,所以號的有效範圍是從0到65535。一般來說,大於49151的號都代表動態。\\n\\n數據報的長度是指包括報頭和數據部分在內的總字節數。因為報頭的長度是固定的,所以該域主要被用來計算可變長度的數據部分(又稱為數據負載)。數據報的最大長度根據操作環境的不同而各異。從理論上說,包含報頭在內的數據報的最大長度為65535字節。不過,一些實際應用往往會限製數據報的大小,有時會降低到8192字節。\\n\\nUDP協議使用報頭中的校驗值來保證數據的安全。校驗值首先在數據發送方通過特殊的演算法計算得出,在傳遞到接收方之後,還需要再重新計算。如果某個數據報在傳輸過程中被第三方篡改或者由於線路噪音等原因受到損壞,發送和接收方的校驗計算值將不會相符,由此UDP協議可以檢測是否出錯。這與TCP協議是不同的,後者要求必須具有校驗值。\\n\\n許多鏈路層協議都提供錯誤檢查,包括流行的以太網協議,也許想知道為什麼UDP也要提供檢查和。其原因是鏈路層以下的協議在源端和終端之間的某些通道可能不提供錯誤檢測。雖然UDP提供有錯誤檢測,但檢測到錯誤時,UDP不做錯誤校正,隻是簡單地把損壞的訊息段扔掉,或者給應用程式提供警告資訊。\\n\\nUDP協議的幾個特性\\n\\nUDP\\n\\n(1)UDP是一個無連接協議,傳輸數據之前源端和終端不建立連接,當\\n\\nUDP它想傳送時就簡單地去抓取來自應\\n\\n用程式的數據,並儘可能快地把它扔到網絡上。在發送端,UDP傳送數據的速度僅僅是受應用程式生成數據的速度、計算機的能力和傳輸帶寬的限製;在接收端,UDP把每個訊息段放在隊列中,應用程式每次從隊列中讀一個訊息段。\\n\\n(2)由於傳輸數據不建立連接,因此也就不需要維護連接狀態,包括收髮狀態等,因此一台服務機可同時向多個客戶機傳輸相同的訊息。\\n\\n(3)UDP資訊包的標題很短,隻有8個字節,相對於TCP的20個字節資訊包的額外開銷很小。\\n\\n(4)吞吐量不受擁擠控製演算法的調節,隻受應用軟件生成數據的速率、傳輸帶寬、源端和終端主機效能的限製。\\n\\n(5)UDP使用儘最大努力交付,即不保證可靠交付,因此主機不需要維持複雜的鏈接狀態表(這裡麵有許多參數)。\\n\\n(6)UDP是麵向報文的。發送方的UDP對應用程式交下來的報文,在新增首部後就向下交付給IP層。既不拆分,也不合併,而是保留這些報文的邊界,因此,應用程式需要選擇合適的報文大小。\\n\\n雖然UDP是一個不可靠的協議,但它是分發資訊的一個理想協議。例如,在螢幕上報告股票市場、在螢幕上顯示航空資訊等等。UDP也用在路由資訊協議RIP(RoutingInformationProtocol)中修改路由表。在這些應用場合下,如果有一個訊息丟失,在幾秒之後另一個新的訊息就會替換它。UDP廣泛用在多媒體應用中,例如,ProgressiveNetworks公司開發的RealAudio軟件,它是在因特網上把預先錄製的或者現場音樂實時傳送給客戶機的一種軟件,該軟件使用的RealAudioaudio-on-demandprotocol協議就是運行在UDP之上的協議,大多數因特網電話軟件產品也都運行在UDP之上。\\n\\n化學中的UDP\\n\\nUDP=uridinediphosphate,尿苷二磷酸,一種嘧啶核苷酸,由堿基、尿嘧啶與核糖組成,主要用途是RNA合成(轉錄)時的原料。另外UDP也是DTP能量消耗後產物,功能類似ADP,但較ADP少見。參與微生物肽聚糖等的合成。\\n\\nUDPvsTCP\\n\\nUDP\\n\\nUDP和TCP協議的主要區彆是兩者在如何實現資訊的可靠傳遞方麵不同。\\n\\nUDPTCP協議中包含了專門的傳遞保證\\n\\n機製,當數據接收方收到發送方傳來的資訊時,會自動向發送方發出確認訊息;發送方隻有在接收到該確認訊息之後才繼續傳送其它資訊,否則將一直等待直到收到確認資訊為止。與TCP不同,UDP協議並不提供數據傳送的保證機製。如果在從發送方到接收方的傳遞過程中出現數據報的丟失,協議本身並不能做出任何檢測或提示。因此,通常人們把UDP協議稱為不可靠的傳輸協議。\\n\\n相對於TCP協議,UDP協議的另外一個不同之處在於如何接收突發性的多個數據報。不同於TCP,UDP並不能確保數據的發送和接收順序。例如,一個位於客戶端的應用程式向服務器發出了以下4個數據報\\n\\nD1\\n\\nD22\\n\\nD333\\n\\nD4444\\n\\n但是UDP有可能按照以下順序將所接收的數據提交到服務端的應用:\\n\\nD333\\n\\nD1\\n\\nD4444\\n\\nD22\\n\\n事實上,UDP協議的這種亂序性基本上很少出現,通常隻會在網絡非常擁擠的情況下纔有可能發生。\\n\\nUDP協議的應用\\n\\n既然UDP是一種不可靠的網絡協議,那麼還有什麼使用價值或必要呢?其實不然,在有些情況下UDP協議可能會變得非常有用。因為UDP具有TCP所望塵莫及的速度優勢。雖然TCP協議中植入了各種安全保障功能,但是在實際執行的過程中會占用大量的係統開銷,無疑使速度受到嚴重的影響。反觀UDP由於排除了資訊可靠傳遞機製,將安全和排序等功能移交給上層應用來完成,極大降低了執行時間,使速度得到了保證。\\n\\n關於UDP協議的最早規範是RFC768,1980年釋出。儘管時間已經很長,但是UDP協議仍然繼續在主流應用中發揮著作用。包括視頻電話會議係統在內的許多應用都證明瞭UDP協議的存在價值。因為相對於可靠性來說,這些應用更加註重實際效能,所以為了獲得更好的使用效果(例如,更高的畫麵幀重新整理速率)往往可以犧牲一定的可靠性(例如,畫麵質量)。這就是UDP和TCP兩種協議的權衡之處。根據不同的環境和特點,兩種傳輸協議都將在今後的網絡世界中發揮更加重要的作用。\\n\\nUDP程式設計\\n\\nUDPServer程式\\n\\n1、編寫UDPServer程式的步驟\\n\\n(1)使用socket()來建立一個UDPsocket,第二個參數為SOCK_DGRAM。\\n\\n(2)初始化sockaddr_in結構的變量,並賦值。sockaddr_in結構定義:\\n\\nstructsockaddr_in{\\n\\nuint8_tsin_len;\\n\\nsa_family_tsin_family;\\n\\nin_port_tsin_port;\\n\\nstructin_addrsin_addr;\\n\\ncharsin_zero[8];\\n\\n};\\n\\n這裡使用“08”作為服務程式的,使用“INADDR_ANY”作為綁定的IP地址即任何主機上的地址。\\n\\n(3)使用bind()把上麵的socket和定義的IP地址和綁定。這裡檢查bind()是否執行成功,如果有錯誤就退出。這樣可以防止服務程式重複運行的問題。\\n\\n(4)進入無限循環程式,使用recvfrom()進入等待狀態,直到接收到客戶程式發送的數據,就處理收到的數據,並向客戶程式發送反饋。這裡是直接把收到的數據發回給客戶程式。\\n\\n2、udpserv.c程式內容\\n\\n#include\\n\\n#include\\n\\n#include\\n\\n#include\\n\\n#include\\n\\n#include\\n\\n#defineMAXLINE80\\n\\n#defineSERV_PORT8888\\n\\nvoiddo_echo(intsockfd,structsockaddr*pcliaddr,socklen_tclilen)\\n\\n{\\n\\nintn;\\n\\nsocklen_tlen;\\n\\ncharmesg[MAXLINE];\\n\\nfor(;;)\\n\\n{\\n\\nlen=clilen;\\n\\n\\/*waitingforreceivedata*\\/\\n\\nn=recvfrom(sockfd,mesg,MAXLINE,0,pcliaddr,&len);\\n\\n\\/*sentdatabacktoclient*\\/\\n\\nsendto(sockfd,mesg,n,0,pcliaddr,len);\\n\\n}\\n\\n}\\n\\nintmain(void)\\n\\n{\\n\\nintsockfd;\\n\\nstructsockaddr_inservaddr,cliaddr;\\n\\nsockfd=socket(AF_INET,SOCK_DGRAM,0);\\/*createasocket*\\/\\n\\n\\/*initservaddr*\\/\\n\\nbzero(&servaddr,sizeof(servaddr));\\n\\nservaddr.sin_family=AF_INET;\\n\\nservaddr.sin_addr.s_addr=htonl(INADDR_ANY);\\n\\nservaddr.sin_port=htons(SERV_PORT);\\n\\n\\/*bindaddressandporttosocket*\\/\\n\\nif(bind(sockfd,(structsockaddr*)&servaddr,sizeof(servaddr))==-1)\\n\\n{\\n\\nperror(\\\"binderror\\\");\\n\\nexit(1);\\n\\n}\\n\\ndo_echo(sockfd,(structsockaddr*)&cliaddr,sizeof(cliaddr));\\n\\nreturn0;\\n\\n}\\n\\nUDPClient程式\\n\\n1、編寫UDPClient程式的步驟\\n\\n(1)初始化sockaddr_in結構的變量,並賦值。這裡使用“8888”作為連接的服務程式的,從命令列參數讀取IP地址,並且判斷IP地址是否符合要求。\\n\\n(2)使用socket()來建立一個UDPsocket,第二個參數為SOCK_DGRAM。\\n\\n(3)使用connect()來建立與服務程式的連接。與TCP協議不同,UDP的connect()並冇有與服務程式三次握手。上麵說了UDP是非連接的,實際上也可以是連接的。使用連接的UDP,kernel可以直接返回錯誤資訊給用戶程式,從而避免由於冇有接收到數據而導致調用recvfrom()一直等待下去,看上去好像客戶程式冇有反應一樣。\\n\\n(4)向服務程式發送數據,因為使用連接的UDP,所以使用write()來替代sendto()。這裡的數據直接從標準輸入讀取用戶輸入。\\n\\n(5)接收服務程式發回的數據,同樣使用read()來替代recvfrom()。\\n\\n(6)處理接收到的數據,這裡是直接輸出到標準輸出上。\\n\\nudpclient.c程式內容:\\n\\n#include\\n\\n#include\\n\\n#include\\n\\n#include\\n\\n#include\\n\\n#include\\n\\n#defineMAXLINE80\\n\\n#defineSERV_PORT8888\\n\\nvoiddo_cli(FILE*fp,intsockfd,structsockaddr*pservaddr,socklen_tservlen)\\n\\n{\\n\\nintn;\\n\\ncharsendline[MAXLINE],recvline[MAXLINE 1];\\n\\n\\/*connecttoserver*\\/\\n\\nif(connect(sockfd,(structsockaddr*)pservaddr,servlen)==-1)\\n\\n{\\n\\nperror(\\\"connecterror\\\");\\n\\nexit(1);\\n\\n}\\n\\nwhile(fgets(sendline,MAXLINE,fp)!=NULL)\\n\\n{\\n\\n\\/*readalineandsendtoserver*\\/\\n\\nwrite(sockfd,sendline,strlen(sendline));\\n\\n\\/*receivedatafromserver*\\/\\n\\nn=read(sockfd,recvline,MAXLINE);\\n\\nif(n==-1)\\n\\n{\\n\\nperror(\\\"readerror\\\");\\n\\nexit(1);\\n\\n}\\n\\nrecvline[n]=0;\\/*terminatestring*\\/\\n\\nfputs(recvline,stdout);\\n\\n}\\n\\n}\\n\\nintmain(intargc,char**argv)\\n\\n{\\n\\nintsockfd;\\n\\nstructsockaddr_insrvaddr;\\n\\n\\/*checkargs*\\/\\n\\nif(argc!=2)\\n\\n{\\n\\nprintf(\\\"usage:udpclient\\\\n\\\");\\n\\nexit(1);\\n\\n}\\n\\n\\/*initservaddr*\\/\\n\\nbzero(&servaddr,sizeof(servaddr));\\n\\nservaddr.sin_family=AF_INET;\\n\\nservaddr.sin_port=htons(SERV_PORT);\\n\\nif(inet_pton(AF_INET,argv,&servaddr.sin_addr)