偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Socket UDP協(xié)議程序代碼

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
下文摘要:文章中,我們對UDP協(xié)議的socket的編程進行了分析。那么大家可以通過文章中的代碼來進行一下參考。希望對您有用。

在網(wǎng)絡(luò)傳輸層,我們除了常用的TCP是進行傳輸?shù)?,還有UDP協(xié)議也是應(yīng)用于傳輸作用。那么這里我們主要極少一下socket發(fā)送UDP協(xié)議數(shù)據(jù)的程序。首先,我們應(yīng)該理解如下概念:UDP是一個簡單的面向數(shù)據(jù)報的傳輸層協(xié)議,我們先站在UDP客戶端的角度來看看如何發(fā)送一個UDP數(shù)據(jù)報,以及協(xié)議棧為發(fā)送一個UDP數(shù)據(jù)報做了哪些事情。UDP數(shù)據(jù)報可以在未連接的socket上發(fā)送(使用sendto系統(tǒng)調(diào)用,指定目的地址),也可以在已連接的socket上發(fā)送(使用send系統(tǒng)調(diào)用,不用指定目的地址),下面我們分兩種情況討論。

下面是一個在未連接的socket上發(fā)送UDP數(shù)據(jù)的用戶態(tài)程序示例(注:該程序的格式和風(fēng)格相當(dāng)不好,只是為臨時測試使用。),該程序目前還只管發(fā)送,不處理接收,關(guān)于接收,我們后面再作分析:

#include<sys/types.h>
#include<sys/socket.h>
#include<sys/ioctl.h>
#include"my_inet.h"
#include<stdio.h>
#include<errno.h>
#include<arpa/inet.h>
#include<unistd.h>
intmain()
{
inti;
structsockaddr_indest;
dest.sin_family=MY_PF_INET;
dest.sin_port=htons(16000);
dest.sin_addr.s_addr=0x013010AC;//目的地址是172.16.48.1(網(wǎng)絡(luò)字節(jié)序)
//創(chuàng)建UDP數(shù)據(jù)報服務(wù)的socket。
intfd=socket(MY_PF_INET,SOCK_DGRAM,MY_IPPROTO_UDP);
if(fd<0){
perror("socket:");
return-1;
}
intbwrite=sendto(fd,"abcdefg",7,0,(structsockaddr*)&dest,sizeof(dest));
if(bwrite==-1){
perror("send:");
close(fd);
return-1;
}
printf("sendto:%d\n",bwrite);
close(fd);
return0;
}

創(chuàng)建socket的操作跟RAW協(xié)議的差不多,只有極少區(qū)別,內(nèi)核中表示套接字的結(jié)構(gòu)上的操作集,協(xié)議名略有不同而已。我們重點看sendto操作所引發(fā)的內(nèi)核代碼執(zhí)行。sendto所到達的my_inet模塊的***站是myinet_sendmsg,一般來講,該函數(shù)只要調(diào)用UDP協(xié)議自己的udp_sendmsg即可,但在之前,它還有一樣事情要完成,就是為這個socket執(zhí)行綁定,這個綁定可能跟服務(wù)器端的bind系統(tǒng)調(diào)用有些區(qū)別。試想,如果我們用這個UDPsocket發(fā)送出去了一個數(shù)據(jù)報,但沒有記錄下這個UDPsocket,那等對端的回應(yīng)數(shù)據(jù)報來的時候,我們就不知道哪個socket要接收這個數(shù)據(jù)報了。綁定就是記錄這個UDPsocket。#p#

myudp_hash是一個具有128項的哈希數(shù)組,每一項都是一個UDPsocket的鏈表,每個UDPsocket以自己的源地址端口號為哈希主鍵插入這個數(shù)組。源地址端口可以是用戶自己指定的,也可以是由內(nèi)核自動分配的。

內(nèi)核自動分配的源端口號有一個范圍,這個范圍段似乎是由系統(tǒng)的內(nèi)存大小決定的(具體有待進一步分析),如果內(nèi)存大(似乎是有高端內(nèi)存可用),范圍段是32768-61000,否則就是1024-4999。udp_port_rover是一個全局變量,初始值為范圍段的下限,每次新分配端口,記錄下新分配的端口號,下一次再分配時,在前一次的基礎(chǔ)上加1,然后查詢對應(yīng)的myudp_hash中的項,如果該項的鏈表不為空,則找下一項,直至遍歷整個數(shù)組,如果為空,則分配成功。所以,當(dāng)連續(xù)分配128個端口后(數(shù)組中的128項中,鏈表全不為空),這個查詢必然失敗,***遍歷數(shù)組完成時,得到的端口號必然是前一次分配的端口號加127,然后,端口號每次加128,再查詢對應(yīng)的數(shù)組項,看該端口號有沒有被使用掉。

這個描述可能有點模糊,簡單總結(jié)一下就是:每次分配一個端口號,先在前一次分配值的基礎(chǔ)上以1為步進值遞增,如果對應(yīng)的哈希數(shù)組中的鏈表為空,則肯定沒有被使用過,直接使用。如果遍歷完整個哈希表都沒有空的鏈表,則要查詢鏈表中的每一項,以得到未使用的端口。

用戶自己指定一個端口,則我們到對應(yīng)的哈希數(shù)組中的鏈表查詢,如果已被使用,并且不能重用,則分配端口號失敗。對用戶自己指定的端口,沒有范圍段的限制。這個一般用于服務(wù)端,而自動分配端口用于客戶端。

綁定完成后,myinet_sendmsg會調(diào)用myudp_sendmsg,它與myraw_sendmsg所執(zhí)行的操作相差并不多。先查詢輸出路由,然后添加協(xié)議首部,***發(fā)送數(shù)據(jù)包。與raw相比,udp要在IP首部前添加一個UDP首部。以下是UDP首部的定義:

structudphdr{
__u16source;//發(fā)送端端口號。
__u16dest;//目的端端口號。
__u16len;//UDP長度。
__u16check;//UDP檢驗和。
};

UDP協(xié)議是一個傳輸層協(xié)議,與下層的網(wǎng)絡(luò)層協(xié)議相比,它不僅需要知道數(shù)據(jù)傳輸?shù)膬啥说闹鳈C,還需要知道是主機上的哪個進程在進行數(shù)據(jù)傳輸,端口號其實就是用于標(biāo)識發(fā)送進程和接收進程的。UDP長度是UDP頭加上UDP數(shù)據(jù)的長度(不包括IP首部)。UDP檢驗和覆蓋UDP首部和UDP數(shù)據(jù)。

由于UDP數(shù)據(jù)報在未連接的socket上進行發(fā)送,所以每次進入myraw_sendmsg,都要進行輸出路由的查詢,以確定源地址和目的地址。但我們知道,路由是有緩存的,所以,并沒有太多的額外開銷。認為在未連接的socket上發(fā)送UDP數(shù)據(jù)報開銷要大的觀點并不完全正確。

責(zé)任編輯:佟健 來源: 互聯(lián)網(wǎng)
相關(guān)推薦

2010-07-17 00:55:48

PHP Telnet

2011-11-09 13:59:27

代碼腐爛

2013-07-29 14:28:43

JQueryJQuery實現(xiàn)分頁分頁程序代碼

2011-11-03 15:44:10

程序員

2009-06-03 14:42:21

Eclipse調(diào)試調(diào)試Java程序

2009-10-26 11:04:36

VB.NET UDP協(xié)

2010-06-29 12:42:05

UDP協(xié)議Java

2010-01-22 15:09:11

VB.NET下載程序

2009-06-17 14:29:50

java程序代碼

2010-07-12 10:15:47

WinSock APIUDP協(xié)議

2014-06-13 13:47:31

UDP

2009-08-24 18:06:36

源程序代碼C#讀取XML文件

2010-01-15 10:48:29

C++程序代碼

2010-03-23 14:12:43

Python開發(fā)Win

2010-07-12 15:40:24

2010-07-06 15:28:57

UDP協(xié)議基礎(chǔ)

2010-07-08 12:58:03

UDP協(xié)議

2010-07-12 14:41:35

UDP協(xié)議

2010-07-06 15:16:34

UDP協(xié)議

2009-09-02 18:28:00

C#鼠標(biāo)位置
點贊
收藏

51CTO技術(shù)棧公眾號