




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
UDP用戶數(shù)據(jù)報協(xié)議UDP是一個簡單的面向數(shù)據(jù)報的運輸層協(xié)議:進程的每個輸出操作都正好產(chǎn)生一個UDP數(shù)據(jù)報,并組裝成一份待發(fā)送的IP數(shù)據(jù)報。這與面向流字符的協(xié)議不同,如TCP,應(yīng)用程序產(chǎn)生的全體數(shù)據(jù)與真正發(fā)送的單個IP數(shù)據(jù)報可能沒有什么聯(lián)系。RFC768是UDP的正式規(guī)范1、UDP報文封裝UDP首部報文格式如下端口號表示發(fā)送進程和接收進程,UDP長度字段指的是UDP首部和UDP數(shù)據(jù)的字節(jié)長度。該字段的最小值為8字節(jié)(發(fā)送一份0字節(jié)的UDP數(shù)據(jù)報是OK的)。這個UDP長度是有冗余的。IP數(shù)據(jù)報長度指的是數(shù)據(jù)報全長,因此UDP數(shù)據(jù)報長度是全長減去IP首部的長度。特點:不可靠、易分片UDP不提供可靠性:它把應(yīng)用程序傳給IP層的數(shù)據(jù)發(fā)送出去,但是并不保證它們能到達目的地。分片:應(yīng)用程序必須關(guān)心IP數(shù)據(jù)報的長度。如果它超過網(wǎng)絡(luò)的MTU,那么就要對IP數(shù)據(jù)報進行分片。如果需要,源端到目的端之間的每個網(wǎng)絡(luò)都要進行分片,并不只是發(fā)送端主機連接第一個網(wǎng)絡(luò)才這樣做。2、IP分片物理網(wǎng)絡(luò)層一般要限制每次發(fā)送數(shù)據(jù)幀的最大長度。任何時候IP層接收到一份要發(fā)送的IP數(shù)據(jù)報時,它要判斷向本地哪個接口發(fā)送數(shù)據(jù)(選路),并查詢該接口獲得其MTU。IP把MTU與數(shù)據(jù)報長度進行比較,如果需要則進行分片。分片可以發(fā)生在原始發(fā)送端主機上,也可以發(fā)生在中間路由器上。把一份IP數(shù)據(jù)報分片以后,只有到達目的地才進行重新組裝。IP首部中部分字段用于報文分片組裝,具體參見tcp/ip協(xié)議學(xué)習(xí)筆記(3)InternetProtocol(IP)對于發(fā)送端發(fā)送的每份IP數(shù)據(jù)報來說,其標(biāo)識字段都包含一個唯一值。該值在數(shù)據(jù)報分片時被復(fù)制到每個片中。標(biāo)志字段用其中一個比特來表示“更多的片”。除了最后一片外,其他每個組成數(shù)據(jù)報的片都要把該比特置1,下面簡單抓一個分片ping包看一下第一片第二片在分片時,除最后一片外,其他每一片中的數(shù)據(jù)部分(除IP首部外的其余部分)必須是8字節(jié)的整數(shù)倍。標(biāo)志字段中有一個比特稱作“不分片”位。如果將這一比特置1,IP將不對數(shù)據(jù)報進行分片。相反把數(shù)據(jù)報丟棄并發(fā)送一個ICMP差錯報文給起始端盡管IP分片過程看起來是透明的,但有一點讓人不想使用它:即使只丟失一片數(shù)據(jù)也要重傳整個數(shù)據(jù)報。為什么會發(fā)生這種情況呢?因為IP層本身沒有超時重傳的機制——由更高層來負責(zé)超時和重傳(TCP有超時和重傳機制,但UDP沒有)IP數(shù)據(jù)報:是指IP層端到端的傳輸單元(在分片之前和重新組裝之后)分組是指在IP層和鏈路層之間傳送的數(shù)據(jù)單元。一個分組可以是一個完整的IP數(shù)據(jù)報,也可以是IP數(shù)據(jù)報的一個分片。3、UDP數(shù)據(jù)報最大長度理論上,IP數(shù)據(jù)報的最大長度是65535字節(jié),這是由IP首部16比特總長度字段所限制的。去除20字節(jié)的IP首部和8個字節(jié)的UDP首部,UDP數(shù)據(jù)報中用戶數(shù)據(jù)的最長長度為65507字節(jié)。但是,大多數(shù)實現(xiàn)所提供的長度比這個最大值小。其中兩個限制因素:第一,應(yīng)用程序可能會受到其程序接口的限制。socketAPI提供了一個可供應(yīng)用程序調(diào)用的函數(shù),以設(shè)置接收和發(fā)送緩存的長度。對于UDPsocket,這個長度與應(yīng)用程序可以讀寫的最大UDP數(shù)據(jù)報的長度直接相關(guān)?,F(xiàn)在的大部分系統(tǒng)都默認提供了可讀寫大于8192字節(jié)的UDP數(shù)據(jù)報第二個限制來自于TCP/IP的內(nèi)核實現(xiàn)。可能存在一些實現(xiàn)特性(或差錯),使IP數(shù)據(jù)報長度小于65535字節(jié)4、UDP服務(wù)器的設(shè)計與實現(xiàn)/*********************************************************************************
*Author
:
wph
*Version
:
1.0
*Date
:
2014/03/01
*Description:
udp
server
*Others
:
*History
:
**********************************************************************************/
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<event2/event.h>
#include
"errocode.h"
#include
"basetype.h"
#define
INVALID_FD
-1
#define
PORT
1234
#define
MAXDATASIZE
512
STATIC
INT
g_iudpFd
=
INVALID_FD;
VOID
udp_callback(evutil_socket_t
fd,
short
what,
void
*arg)
{
struct
sockaddr_in
client;
socklen_t
addrlen;
int
num;
char
buf[MAXDATASIZE];
memset(buf,
0,
MAXDATASIZE);
num
=
recvfrom(fd,
buf,
MAXDATASIZE,
0,
(struct
sockaddr*)&client,
&addrlen);
if
(num
<
0)
{
perror("recvfrom()
error\n");
exit(1);
}
printf("You
got
a
message
(%s)
from
client.\nIt's
ip
is%s,
port
is
%d.\n",
buf,
inet_ntoa(client.sin_addr),
htons(client.sin_port));
sendto(fd,
buf,
num,
0,
(struct
sockaddr
*)&client,
addrlen);
}
ULONG
udp_init(VOID)
{
int
sockfd;
struct
sockaddr_in
server;
/*
The
caller
has
already
set
up
fd1,
fd2
somehow,
and
make
them
nonblocking.
*/
sockfd
=
socket(AF_INET,
SOCK_DGRAM,
0);
if(INVALID_FD
==
sockfd)
{
perror("Creatingsocket
failed.");
exit(1);
}
bzero(&server,
sizeof(server));
server.sin_family
=
AF_INET;
server.sin_port=
htons(PORT);
server.sin_addr.s_addr=
htonl(INADDR_ANY);
if(-1
==
bind(sockfd,
(struct
sockaddr
*)&server,
sizeof(server)))
{
perror("Bind()error.");
exit(1);
}
g_iudpFd
=
sockfd;
return
EROOR_SUCCESS;
}
VOID
udp_fini(VOID)
{
int
sockfd
=
g_iudpFd;
if
(INVALID_FD
!=
sockfd)
{
close(sockfd);
}
}
VOID
main_loop(VOID)
{
INT
ifd
=
g_iudpFd;
struct
event
*ev1;
struct
timeval
five_seconds
=
{5,0};
struct
event_base
*base
=
event_base_new();
/*
upd
服務(wù)器采用libevet進行處理
*/
ev1
=
event_new(base,
ifd,
EV_TIMEOUT|EV_READ|EV_PERSIST,
udp_callback,
NULL);
event_add(ev1,
&five_seconds);
event_base_dispatch(base);
return
;
}
INT
main()
{
if(EROOR_SUCCESS
!=
udp_init())
{
return
-1;
}
main_loop();
udp_fini();
return
0;
}
/*********************************************************************************
*Copyright(C),2010-2011,
*Author
:
wph
*Version
:
1.0
*Date
:
2014/03/01
*Description:
udp
client
*Others
:
*History
:
**********************************************************************************/
#include
<stdio.h>
#include
<stdlib.h>
#include
<unistd.h>
#include
<string.h>
#include
<sys/types.h>
#include
<sys/socket.h>
#include
<netinet/in.h>
#include
<netdb.h>
#include
"errocode.h"
#include
"basetype.h"
#define
INVALID_FD
-1
#define
PORT
1234
#define
MAXDATASIZE
512
INT
main(INT
argc,
CHAR
*argv[])
{
INT
isockfd
=
INVALID_FD;
UINT
uinum
=
0;
char
buf[MAXDATASIZE];
socklen_t
addrlen;
struct
hostent
*he;
struct
sockaddr_in
server;
struct
sockaddr_in
peer;
if
(3
!=
argc)
{
printf("Usage:
%s
<IP
Address><message>\n",
argv[0]);
exit(1);
}
if
(NULL
==
(he=gethostbyname(argv[1])))
{
printf("gethostbyname()error\n");
exit(1);
}
if
(INVALID_FD
==
(isockfd
=
socket(AF_INET,
SOCK_DGRAM,0)))
{
printf("socket()
error\n");
exit(1);
}
bzero(&server,sizeof(server));
server.sin_family
=
AF_INET;
server.sin_port
=
htons(PORT);
server.sin_addr=
*((struct
in_addr
*)he->h_addr);
sendto(isockfd,
argv[2],strlen(argv[2]),0,(struct
sockaddr
*)&server,sizeof(server));
addrlen=sizeof(server);
while
(1)
{
if((uinum=recvfrom(isockfd,
buf,
MAXDATASIZE,
0,
(struct
sockaddr
*)&peer,
&addrlen))==
-1)
{
printf("recvfrom()
error\n");
exit(1);
}
if
(addrlen
!=
sizeof(server)
||
memcmp((const
void
*)&server,
(const
void
*)&peer,
addrlen)
!=
0)
{
printf("
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 建筑工程項目施工總承包合同
- 承債式公司股權(quán)轉(zhuǎn)讓協(xié)議
- 站臺裝修勞務(wù)合同
- 房屋出租合同協(xié)議書
- 債轉(zhuǎn)股投資合同協(xié)議書
- 裝修材料采購合同
- 二婚離婚協(xié)議書新
- 電商行業(yè)網(wǎng)絡(luò)購物服務(wù)協(xié)議
- 影視內(nèi)容版權(quán)采購協(xié)議
- 手房買賣合同官方
- 關(guān)于與旅游發(fā)展集團成立合資公司的可行性研究報告
- 第一部分-氣排球運動介紹課件
- 世界局勢與主再來課件
- 思維游戲(小孩都喜歡玩的游戲)教學(xué)內(nèi)容課件
- 儲能技術(shù)課后參考答案梅生偉
- 過渡金屬氧化物催化劑及其催化作用
- 溫濕度對果蔬儲存的影響
- 遺傳性耳聾基因檢測標(biāo)準Ppt
- 電是怎么產(chǎn)生的
- 八-十-天-環(huán)-游-地-球(讀書)專題培訓(xùn)課件
- 新概念英語第一冊課文完整版
評論
0/150
提交評論