Linux 網路程式設計之UDP

2021-06-23 04:20:32 字數 4200 閱讀 5670

** 

1.介紹

udp協議是無連線的,不可靠傳輸的協議. 伺服器與客戶端的互動不需要建立連線,沒有流量控制的功能。與tcp一樣,它也是傳輸層協議,通訊過程中需要ip位址與埠號。使用udp進行程式設計包括伺服器與客戶端,下面介紹一下伺服器與客戶端的通訊流程:

伺服器流程:

(1)建立伺服器套接字描socket

(2)將位址結構繫結到套接字上 bind

(3)資料傳輸 sendto/recvfrom (不需要連線,所心沒有監聽)

(4)關閉套接字close

客戶端流程:

(1)建立客戶端套接字 socket

(2)設定伺服器端口

(3)資料傳輸 sendto/recvfrom

(4)關閉套接字close

可以看出,與tcp通訊相比,udp伺服器沒有監聽埠與等待連線的過程,而客戶端沒有建立連線的過程.

2. 相關函式

int socket(int domain,int type,int protocol);

type: sock_dgram 資料報

#include

#include

ssize_t recvfrom(int s,void*buf,size_t len,int flags,struct sockaddr* from,socklen_t *fromlen);

引數:s-套接字描述符

buf-接收資料的緩衝區大小

len-接收資料的緩衝區長度

flags-接收資料的標誌

from-客戶端或者是伺服器的位址

fromlen-客戶端或者是伺服器的位址長度指標

返回值:

成功返回接收的位元組數,發生錯誤時返回-1.

#include

#include

ssize_t sendto(int s,const void*buf,size_t len,int flags,const struct sockaddr*to,socklen_t tolen);

引數:s-套接字描述符

buf-傳送緩衝區指標,const型別,由於傳送的時候已經把資料寫入buf了.

len-傳送資料的實際長度

flags-傳送資料的標誌

to-傳送的目的位址結構

tolen-目的位址結構長度

返回值:

成功返回傳送的位元組數,失敗返回-1. 返回0也是合法的表示沒有接收到資料。

3. udp例項

伺服器:

#include

#include

#include

#include

#include

#include

/**與tcp程式設計相比,udp缺少了connect(),listen(),accept()函式,這是由於udp無連線的特性決定的

udp伺服器端:

(1)建立資料報套接字socket

(2)繫結伺服器的ip位址與埠號到套接字bind

(3)接收客戶端的資料recvfrom

(4)向客戶端傳送資料sendto

(5)關閉套接字close()

recvfrom/sendto函式的介紹:

ssize_t recvfrom(int s,void*buf,size_t len,int flags,struct sockaddr* from,socklen_t *fromlen);

第1個引數表示套接字描述符

第2個引數表示接收資料的緩衝區

第3個引數表示接收緩衝區的長度

第4個引數傳送標誌,msg_dontwait

第5個引數表示傳送方的位址資訊 struct sockaddr*

第6個引數表示傳送方的位址長度sizeof(struct sockaddr_in)

返回值:

成功返回接收的位元組數,返回0表示接收的位元組數為0,返回-1表示發生錯誤,錯誤碼放在errno

ssize_t sendto(int s,const void*buf,size_t len,int flags,const struct sockaddr* to,socklen_t tolen);

第1個引數表示套接字描述符

第2個引數表示傳送緩衝區的指標

第3個引數表示傳送緩衝區的大小

第4個引數是標誌

第5個引數表示目的主機的sockaddr_in指標

第6個引數表示目的主機的sizeof(struct sockaddr_in);

返回值:

成功返回已經傳送的資料長度,資料長度可以為0

-1表示發生錯誤,錯誤碼儲存在errno

**/#define port 8888

int main(int agrc,char*argv)

memset(&server_addr,0,sizeof(server_addr));//將位址結構清0

server_addr.sin_family=af_inet;

server_addr.sin_port=htons(port);

server_addr.sin_addr.s_addr=htonl(inaddr_any);//任意位址,主機位元組序轉換為網路位元組序

int ret=bind(s,(struct sockaddr*)&server_addr,sizeof(server_addr));//將ip位址與埠號繫結到套接字上,表示伺服器用此埠號進行資料的接收與傳送

if(ret<0)

//利用for迴圈進行資料的傳送與接收

for(;;)

sendto(s,buffer,rec,0,(struct sockaddr*)&client_addr,len);//將資料從伺服器端傳送給客戶端client_addr表示目我位址資訊,len指目我位址長度資訊

//client_addr儲存著客戶

char *addr;

addr=(char*)inet_ntoa(client_addr.sin_addr);//返回值為一靜態記憶體的指標,全域性的,執行緒不安全,是不可重入的

// char addr[16];

// inet_ntop(af_inet,(void*)&client_addr.sin_addr,addr,16);//協議族,in_addr指標,字元陣列,陣列長度

printf("client ip is:%s\n",addr);

int port=ntohs(client_addr.sin_port);//輸出客戶端的所使用的埠號

printf("port is:%d\n",port);

}close(s);

return 0;

}客戶端:

#include

#include

#include

#include

#include

#include

#define port 8888

/**udp客戶端:

(1)建立套接字描述符

(2)向伺服器傳送資料sendto

(3)接收伺服器傳送的資料recvfrom

(4)關閉套接字close()

**/int main(int argc,char*argv)

memset(&server_addr,0,sizeof(server_addr));//將位址結構清0

server_addr.sin_family=af_inet;

server_addr.sin_port=htons(port);

server_addr.sin_addr.s_addr=htonl(inaddr_any);

//首先向伺服器傳送資料

char buffer[1024];

int size;

int len=sizeof(server_addr);

bzero(buffer,1024);

for(;;)}}

}執行結果:

[root@localhost ~]# ./udp-s

6server:hello

client ip is:127.0.0.1

port is:46239

[root@localhost ~]# ./udp-c

hello

server ip:127.0.0.1

server port:8888

recevied:hello

總結:本文主要介紹了linux udp程式設計的基本流程,最後給出乙個udp程式設計的例子。

linux網路程式設計之UDP

udp 前面已經講過tcp網路通訊,然後tcp每次通訊都要進行三次握手連線,雖然傳輸的可靠性比較高,但對於一些及時性的資料的傳輸顯得太過費時,所以就有了udp這種無連線通訊,但資料容易出錯。伺服器端填充 sockaddr結構 bzero addr,sizeof struct sockaddr in ...

Linux網路程式設計之UDP

一 概述 udp 是 user datagram protocol 的簡稱,中文名是使用者資料報協議,是乙個簡單的面向資料報的運輸層協議,在網路中用於處理資料報,是一種無連線的協議。udp 不提供可靠性的傳輸,它只是把應用程式傳給 ip 層的資料報傳送出去,但是並不能保證它們能到達目的地。由於 ud...

Linux網路程式設計之UDP洪水攻擊

1.概述 udp攻擊向目標主機的udp埠傳送大量的udp報文,造成目標主機的埠堵塞,達到攻擊的目的。建立多執行緒,利用原始套接字封裝udp與ip的首部,然後傳送udp報文,攻擊目標主機.2.udp攻擊例項 include include include include include include...