導航:首頁 > 編程語言 > udpsocket編程linux

udpsocket編程linux

發布時間:2025-08-12 07:36:37

㈠ 基於Linux的遠程指令系統(使用udp而不是tcp)

一. Linux下UDP編程框架

使用UDP進行程序設計可以分為客戶端和伺服器端兩部分。
1.伺服器端程序包括:
? 建立套接字
? 將套接字地址結構進行綁定
? 讀寫數據
? 關閉套接字
2.客戶端程序包括:
? 建立套接字
? 讀寫數據
? 關閉套接字
3.伺服器端和客戶端程序之間的差別
伺服器端和客戶端兩個流程之間的主要差別在於對地址的綁定函數(bind()函數),而客戶端可以不用進行地址和埠的綁定操作。

二.Linux中UDP套接字函數

從圖可知,UDP協議的服務端程序設計的流程分為套接字建立,套接字與地址結構進行綁定,收發數據,關閉套接字;客戶端程序流程為套接字建立,收發數據,關閉套接字等過程。它們分別對應socket(),bind(),sendto(),recvfrom(),和close()函數。
網路程序通過調用socket()函數,會返回一個用於通信的套接字描述符。Linux應用程序在執行任何形式的I/O操作的時候,程序是在讀或者寫一個文件描述符。因此,可以把創建的套接字描述符看成普通的描述符來操作,並通過讀寫套接字描述符來實現網路之間的數據交流。
1. socket
1> 函數原型:
int socket(int domain,int type,int protocol)
2> 函數功能:
函數socket()用於創建一個套接字描述符。
3> 形參:
? domain:用於指定創建套接字所使用的協議族,在頭文件
中定義。
常見的協議族如下:
AF_UNIX:創建只在本機內進行通信的套接字。
AF_INET:使用IPv4 TCP/IP協議
AF_INET6:使用IPv6 TCP/IP協議
說明:
AF_UNIX只能用於單一的UNIX系統進程間通信,而AF_INET是針對Interne的,因而可以允許在遠程主機之間通信。一般把它賦為AF_INET。
? type:指明套接的類型,對應的參數如下
SOCK_STREAM:創建TCP流套接字
SOCK_DGRAM:創建UDP數據報套接字
SOCK_RAW:創建原始套接字
? protocol:
參數protocol通常設置為0,表示通過參數domain指定的協議族和參數type指定的套接字類型來確定使用的協議。當為原始套接字時,系統無法唯一的確定協議,此時就需要使用使用該參數指定所使用的協議。
4> 返回值:執行成功後返回一個新創建的套接字;若有錯誤發生則返回一個-1,錯誤代碼存入errno中。
5> 舉例:調用socket函數創建一個UDP套接字
int sock_fd;
sock_fd = socket(AF_INET,SOCK_DGRAM,0);
if(sock_fd < 0){
perror(「socket」);
exit(1);
}
2. bind
1> 函數原型:
int bind(int sockfd,struct sockaddr *my_addr,socklen_taddrlen)
2> 函數功能
函數bind()的作用是將一個套接字文件描述符與一個本地地址綁定在一起。
3> 形參:
? sockfd:sockfd是調用socket函數返回的文件描述符;
? addrlen是sockaddr結構的長度。
? my_addr: 是一個指向sockaddr結構的指針,它保存著本地套接字的地址(即埠和IP地址)信息。不過由於系統兼容性的問題,一般不使用這個結構,而使用另外一個結構(struct sockaddr_in)來代替
4> 套接字地址結構:
(1)structsockaddr:
結構struct sockaddr定義了一種通用的套接字地址,它在
Linux/socket.h 中定義。
struct sockaddr{
unsigned short sa_family;/*地址類型,AF_XXX*/
char sa_data[14];/*14位元組的協議地址*/
}
a. sin_family:表示地址類型,對於使用TCP/IP協議進行的網路編程,該值只能是AF_INET.
b. sa_data:存儲具體的協議地址。
(2)sockaddr_in
每種協議族都有自己的協議地址格式,TCP/IP協議組的地址格式為結構體struct sockaddr_in,它在netinet/in.h頭文件中定義。
struct sockaddr_in{
unsigned short sin_family;/*地址類型*/
unsigned short sin_port;/*埠號*/
struct in_addr sin_addr;/*IP地址*/
unsigned char sin_zero[8];/*填充位元組,一般賦值為0*/
}
a. sin_family:表示地址類型,對於使用TCP/IP協議進行的網路編程,該值只能是AF_INET.
b. sin_port:是埠號
c. sin_addr:用來存儲32位的IP地址。
d. 數組sin_zero為填充欄位,一般賦值為0.
e. structin_addr的定義如下:
struct in_addr{
unsignedlong s_addr;
}
結構體sockaddr的長度為16位元組,結構體sockaddr_in的長度為16位元組。可以將參數my_addr的sin_addr設置為INADDR_ANY而不是某個確定的IP地址就可以綁定到任何網路介面。對於只有一IP地址的計算機,INADDR_ANY對應的就是它的IP地址;對於多宿主主機(擁有多個網卡),INADDR_ANY表示本伺服器程序將處理來自所有網路介面上相應埠的連接請求
5> 返回值:
函數成功後返回0,當有錯誤發生時則返回-1,錯誤代碼存入errno中。
6>舉例:調用socket函數創建一個UDP套接字
struct sockaddr_in addr_serv,addr_client;/*本地的地址信息*/
memset(&serv_addr,0,sizeof(struct sockaddr_in));
addr_serv.sin_family = AF_INET;/*協議族*/
addr_serv.sin_port = htons(SERV_PORT);/*本地埠號*/
addr_serv.sin_addr.s_addr = htonl(INADDR_ANY); /*任意本地地址*/
/*套接字綁定*/
if(bind(sock_fd,(struct sockaddr *)&addr_serv),sizeof(structsockaddr_in)) <0)
{
perror(「bind」);
exit(1);
}
3.close
1>函數原型:
int close(intfd);
2>函數功能:
函數close用來關閉一個套接字描述符。
3>函數形參:
? 參數fd為一個套接字描述符。
4>返回值:
執行成功返回0,出錯則返回-1.錯誤代碼存入errno中。
說明:
以上三個函數中,前兩個要包含頭文件
#include
#include
後一個包含:
#include
4.sendto
1>函數原型:
#include
#include
ssize_t sendo(ints,const void *msg,size_t len,int flags,const struct sockaddr *to,socklen_ttolen);
2>函數功能:
向目標主機發送消息
3>函數形參:
? s:套接字描述符。
? *msg:發送緩沖區
? len:待發送數據的長度
? flags:控制選項,一般設置為0或取下面的值
(1)MSG_OOB:在指定的套接字上發送帶外數據(out-of-band data),該類型的套接字必須支持帶外數據(eg:SOCK_STREAM).
(2)MSG_DONTROUTE:通過最直接的路徑發送數據,而忽略下層協議的路由設置。
? to:用於指定目的地址
? tolen:目的地址的長度。
4>函數返回值:
執行成功後返回實際發送數據的位元組數,出錯返回-1,錯誤代碼存入errno中。
5>函數舉例:
char send_buf[BUFFERSIZE];
struct sockaddr_in addr_client;

memset(&addr_client,0,sizeof(struct sockaddr_in));
addr_client.sin_family = AF_INET;
addr_client.sin_port = htons(DEST_PORT);
if(inet_aton(「172.17.242.131」,&addr_client.sin_addr)<0){
perror(「inet_aton」);
exit(1);
}
if(sendto(sock_fd,send_buf,len,0,(strut sockaddr*)&addr_client,sizeof(struct sockaddr_in)) <0){
perror(「sendto」);
exit(1);
}
5.recvfrom
1>函數原型:
#include
#include
ssize_t recvfrom(int s,void *buf,size_t len,intflags,struct sockaddr *from,socklen_t *fromlen);
2>函數功能:接收數據
3>函數形參:
? int s:套接字描述符
? buf:指向接收緩沖區,接收到的數據將放在這個指針所指向的內存空間。
? len:指定了緩沖區的大小。
? flags:控制選項,一般設置為0或取以下值
(1)MSG_OOB:請求接收帶外數據
(2)MSG_PEEK:只查看數據而不讀出
(3)MSG_WAITALL:只在接收緩沖區時才返回。
? *from:保存了接收數據報的源地址。
? *fromlen:參數fromlen在調用recvfrom前為參數from的長度,調用recvfrom後將保存from的實際大小。
4>函數返回值:
執行成功後返回實際接收到數據的位元組數,出錯時則返回-1,錯誤代碼存入errno中。
5>函數實例:
char recv_buf[BUFFERSIZE];
struct sockaddr_in addr_client;
int src_len;
src_len = sizeof(struct sockaddr_in);
int src_len;
src_len = sizeof(struct sockaddr_in);
if(recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(structsockaddr *)&src_addr,&src_len)<0){
perror(「again_recvfrom」);
exit(1);
}
三.UDP編程實例

客戶端向伺服器發送字元串Hello tiger,伺服器接收到數據後將接收到字元串發送回客戶端。

1.伺服器端程序
1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9
10 #define SERV_PORT 3000
11
12 int main()
13 {
14 int sock_fd; //套接子描述符號
15 int recv_num;
16 int send_num;
17 int client_len;
18 char recv_buf[20];
19 struct sockaddr_in addr_serv;
20 struct sockaddr_in addr_client;//伺服器和客戶端地址
21 sock_fd = socket(AF_INET,SOCK_DGRAM,0);
22 if(sock_fd < 0){
23 perror("socket");
24 exit(1);
25 } else{
26
27 printf("sock sucessful\n");
28 }
29 //初始化伺服器斷地址
30 memset(&addr_serv,0,sizeof(struct sockaddr_in));
31 addr_serv.sin_family = AF_INET;//協議族
32 addr_serv.sin_port = htons(SERV_PORT);
33 addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);//任意本地址
34
35 client_len = sizeof(struct sockaddr_in);
36 /*綁定套接子*/
37 if(bind(sock_fd,(struct sockaddr *)&addr_serv,sizeof(struct sockaddr_in))<0 ){
38 perror("bind");
39 exit(1);

40 } else{
41
42 printf("bind sucess\n");
43 }
44 while(1){
45 printf("begin recv:\n");
46 recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_client,&client_len);
47 if(recv_num < 0){
48 printf("bad\n");
49 perror("again recvfrom");
50 exit(1);
51 } else{
52 recv_buf[recv_num]='\0';
53 printf("recv sucess:%s\n",recv_buf);
54 }
55 printf("begin send:\n");
56 send_num = sendto(sock_fd,recv_buf,recv_num,0,(struct sockaddr *)&addr_client,client_len);
57 if(send_num < 0){
58 perror("sendto");
59 exit(1);
60 } else{
61 printf("send sucessful\n");
62 }
63 }
64 close(sock_fd);
65 return 0;
66 }

2.客戶端程序
1 #include
2 #include
3 #include
4 #include
5 #include
6
7 #include
8 #include
9 #include
10
11 #define DEST_PORT 3000
12 #define DSET_IP_ADDRESS "192.168.1.103"
13
14 int main()
15 {
16 int sock_fd;/*套接字文件描述符*/
17 int send_num;
18 int recv_num;
19 int dest_len;
20 char send_buf[20]={"hello tiger"};
21 char recv_buf[20];
22 struct sockaddr_in addr_serv;/*服務端地址,客戶端地址*/
23
24 sock_fd = socket(AF_INET,SOCK_DGRAM,0);//創建套接子
25 //初始化伺服器端地址
26 memset(&addr_serv,0,sizeof(addr_serv));
27 addr_serv.sin_family = AF_INET;
28 addr_serv.sin_addr.s_addr = inet_addr(DSET_IP_ADDRESS);
29 addr_serv.sin_port = htons(DEST_PORT);
30
31 dest_len = sizeof(struct sockaddr_in);
32 printf("begin send:\n");
33 send_num = sendto(sock_fd,send_buf,sizeof(send_buf),0,(struct sockaddr *)&addr_serv,dest_len);
34 if(send_num < 0){
35 perror("sendto");
36 exit(1);
37 } else{
38
39 printf("send sucessful:%s\n",send_buf);

40 }
41 recv_num = recvfrom(sock_fd,recv_buf,sizeof(recv_buf),0,(struct sockaddr *)&addr_serv,&dest_len);
42 if(recv_num <0 ){
43
44 perror("recv_from");
45 exit(1);
46 } else{
47 printf("recv sucessful\n");
48 }
49 recv_buf[recv_num]='\0';
50 printf("the receive:%s\n",recv_buf);
51 close(sock_fd);
52 return 0;
53 }

㈡ Linux C/C++ UDP socket通信

Linux C/C++進行UDP socket通信時,其Server端與Client端的主要流程各有不同。Server端流程包括初始化socket,綁定埠與地址,接收數據並處理後,發送回應至客戶端。而Client端則需要創建socket,獲取Server地址與埠信息,接著發送請求數據,接收Server回應。

在進行UDP通信時,需用到四個關鍵API,分別是socket(),bind(),sendto()與recvfrom()。掌握這四個函數,便能熟練地利用UDP進行各種數據傳輸。

在UDP通信中,地址與埠的配置是通過sockaddr_in結構體來完成的。該結構體包括了IP地址、埠號、網路位元組序等信息,便於程序准確地設置與識別通信目標。

具體來說,消息的發送與接收主要通過sendto()與recvfrom()函數來完成。sendto()函數用於發送數據包至指定目標,而recvfrom()則用於接收從任意地址發送來的數據包。這兩個函數的使用,使得UDP通信在靈活性與效率上都有了顯著提升。

為了驗證上述流程與函數的正確性,通常會編寫測試程序。Server端程序會監聽特定埠,接收客戶端發送的數據,並進行處理後將回應發回。同時,Client端程序則會嘗試連接Server端並發送測試數據,接收Server的回應,以此測試通信的穩定性和數據傳輸的正確性。

閱讀全文

與udpsocket編程linux相關的資料

熱點內容
加密解密數學講座 瀏覽:234
反編譯亂碼字元 瀏覽:150
java復制構造 瀏覽:433
數學u和n的演算法 瀏覽:110
建築設計防火規范pdf 瀏覽:109
資陽數控編程培訓怎麼學 瀏覽:324
u盤文件夾選項 瀏覽:954
自動化交易演算法 瀏覽:690
單片機編譯過程 瀏覽:376
空氣的壓縮率 瀏覽:432
android定製ui 瀏覽:966
魔獸世界任務命令 瀏覽:176
阿里程序員聖誕彩蛋 瀏覽:584
列印機打不了pdf文件 瀏覽:967
家用空調什麼壓縮機好 瀏覽:3
雲伺服器免費社區 瀏覽:379
圖片加密解密c語言 瀏覽:911
排序演算法的面試題 瀏覽:429
加密的密碼轉換 瀏覽:510
解壓失敗c盤還能用嗎 瀏覽:348