UDP編程步驟
在C語言中進(jìn)行UDP編程的一般步驟如下:
(1)包含頭文件:
在代碼中包含必要的頭文件,以便使用UDP編程所需的函數(shù)和數(shù)據(jù)類型。通常情況下,你需要包含 <sys/socket.h>、<netinet/in.h> 和 <arpa/inet.h>。
(2)創(chuàng)建套接字:
使用 socket() 函數(shù)創(chuàng)建一個(gè)套接字,該套接字將用于網(wǎng)絡(luò)通信。套接字是一個(gè)整數(shù)值,它表示一個(gè)打開的文件描述符,用于在網(wǎng)絡(luò)上發(fā)送和接收數(shù)據(jù)。
(3)設(shè)置地址和端口:
創(chuàng)建一個(gè) struct sockaddr_in 結(jié)構(gòu)體,并設(shè)置其中的成員變量,包括地址和端口號(hào)。這個(gè)結(jié)構(gòu)體用于指定服務(wù)器的地址和端口。
(4)綁定套接字:
使用 bind() 函數(shù)將套接字綁定到指定的地址和端口上。這將使服務(wù)器能夠接收通過該地址和端口發(fā)送的UDP數(shù)據(jù)報(bào)。
(5)接收數(shù)據(jù):
使用 recvfrom() 函數(shù)從綁定的套接字接收數(shù)據(jù)報(bào)。該函數(shù)將阻塞等待,直到接收到數(shù)據(jù)報(bào)為止。
(6)發(fā)送數(shù)據(jù):
使用 sendto() 函數(shù)向特定的目標(biāo)地址發(fā)送數(shù)據(jù)報(bào)。該函數(shù)需要指定目標(biāo)地址和端口,以及要發(fā)送的數(shù)據(jù)。
(7)關(guān)閉套接字:
在通信結(jié)束后,使用 close() 函數(shù)關(guān)閉套接字,釋放資源。
這些步驟提供了一個(gè)基本的框架來進(jìn)行UDP編程。你可以根據(jù)需要進(jìn)行適當(dāng)?shù)男薷暮蛿U(kuò)展。同時(shí)還需要處理錯(cuò)誤和異常情況,并確保適當(dāng)?shù)蒯尫刨Y源,以避免內(nèi)存泄漏和其他問題。請(qǐng)注意,UDP是面向無連接的協(xié)議,因此不需要像TCP那樣建立連接和維護(hù)狀態(tài)。每個(gè)UDP數(shù)據(jù)報(bào)都是獨(dú)立的,它們可以單獨(dú)發(fā)送和接收。
通信流程
server
(1)創(chuàng)建數(shù)據(jù)報(bào)套接字(socket(,SOCK_DGRAM,))
(2)綁定網(wǎng)絡(luò)信息(bind())
(3)接收信息(recvfrom())
(4)關(guān)閉套接字(close())文章來源:http://www.zghlxwxcb.cn/news/detail-446254.html
client
(1)創(chuàng)建數(shù)據(jù)報(bào)套接字(socket())
(2)指定服務(wù)器的網(wǎng)絡(luò)信息
(3)發(fā)送信息(sendto())
(4)關(guān)閉套接字(close())文章來源地址http://www.zghlxwxcb.cn/news/detail-446254.html
函數(shù)接口
socket
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int socket(int domain,int type,int protocol);
功能:創(chuàng)建套接字文件
參數(shù):
domain:協(xié)議族 ,選擇通信方式
AF_UNIX, AF_LOCAL 本地通信
AF_INET IPv4
AF_INET6 IPv6
type:通信協(xié)議-套接字類型
SOCK_STREAM 流式套接字
SOCK_DGRAM 數(shù)據(jù)報(bào)套接字
SOCK_RAW 原始套接字
protocol:協(xié)議 填0,自動(dòng)匹配底層TCP或UDP等協(xié)議。根據(jù)type匹配系統(tǒng)默認(rèn)自動(dòng)幫助匹配對(duì)應(yīng)協(xié)議
傳輸層:IPPROTO_TCP、IPPROTO_UDP、IPPROTO_ICMP
網(wǎng)絡(luò)層:htons(ETH_P_IP|ETH_P_ARP|ETH_P_ALL)
返回值:成功。返回同于鏈接的文件描述符
失敗 -1,更新errno
bind
```c
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen);
功能:綁定套接字 - ip和端口
功能:
sockfd:套接字文件描述符
addr:用于通信結(jié)構(gòu)體 (提供的是通用結(jié)構(gòu)體,需要根據(jù)選擇通信方式,填充對(duì)應(yīng)結(jié)構(gòu)體-通信結(jié)構(gòu)體由socket第一個(gè)參數(shù)確定)
addrlen:結(jié)構(gòu)體大小
返回值: 成功0
失敗:-1 更新errno
通用結(jié)構(gòu)體:
struct sockaddr{
sa_family_t sa_family;
char sa_data[14];
}
ipv4的通信結(jié)構(gòu)體:
struct sockaddr_in{
sa_family_t sin_family;/*AF_INET */
in_port_t sin_port;/* 端口 */
struct in_addr sin_addr;/* ip地址 */
};
struct in_addr{
uint32_t s_addr;
};
本地通信結(jié)構(gòu)體:
struct sockaddr_un{
sa_family_t sun_family;/* AF_UNIX */
char sun_path[108];/* 套接字文件 */
};
recvfrom
ssize_t recvfrom(int sockfd,void*buf,size_t len,int flags,
struct sockaddr * src_addr,socklen_t * addrlen);
功能:接收數(shù)據(jù)
參數(shù):
sockfd:套接字描述符
buf:接收緩存區(qū)的首地址
len:接收緩存區(qū)的大小
flags:0//調(diào)用方式標(biāo)志位
src_addr:發(fā)送端的網(wǎng)絡(luò)信息結(jié)構(gòu)體的指針
addrlen:發(fā)送端的網(wǎng)絡(luò)信息結(jié)構(gòu)體的大小的指針
返回值:
成功接收的字節(jié)個(gè)數(shù)
失?。?span id="n5n3t3z" class="token operator">-1
0:客戶端退出
sendto
ssize_t sendto(int sockfd,constvoid*buf,size_t len,int flags,
const struct sockaddr* dest_addr,socklen_t addrlen);
功能:發(fā)送數(shù)據(jù)
參數(shù):
sockfd:套接字描述符
buf:發(fā)送緩存區(qū)的首地址
len:發(fā)送緩存區(qū)的大小
flags:0
src_addr:接收端的網(wǎng)絡(luò)信息結(jié)構(gòu)體的指針
addrlen:接收端的網(wǎng)絡(luò)信息結(jié)構(gòu)體的大小
返回值:
成功發(fā)送的字節(jié)個(gè)數(shù)
失?。?span id="n5n3t3z" class="token operator">-1
舉例
UDP客戶端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAX_BUFFER_SIZE 1024
#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 8888
int main() {
int sockfd;
struct sockaddr_in server_addr;
char buffer[MAX_BUFFER_SIZE];
// 創(chuàng)建UDP套接字
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&server_addr, 0, sizeof(server_addr));
// 設(shè)置服務(wù)器地址和端口
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
server_addr.sin_port = htons(SERVER_PORT);
// 從標(biāo)準(zhǔn)輸入讀取數(shù)據(jù)
printf("Enter message: ");
fgets(buffer, MAX_BUFFER_SIZE, stdin);
// 發(fā)送數(shù)據(jù)到服務(wù)器
sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr*)&server_addr, sizeof(server_addr));
// 等待接收服務(wù)器的響應(yīng)
memset(buffer, 0, sizeof(buffer));
recvfrom(sockfd, buffer, sizeof(buffer), 0, NULL, NULL);
// 打印服務(wù)器的響應(yīng)
printf("Server response: %s\n", buffer);
// 關(guān)閉套接字
close(sockfd);
return 0;
}
UDP服務(wù)器
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define MAX_BUFFER_SIZE 1024
#define SERVER_PORT 8888
int main() {
int sockfd;
struct sockaddr_in server_addr, client_addr;
char buffer[MAX_BUFFER_SIZE];
// 創(chuàng)建UDP套接字
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
memset(&server_addr, 0, sizeof(server_addr));
memset(&client_addr, 0, sizeof(client_addr));
// 設(shè)置服務(wù)器地址和端口
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(SERVER_PORT);
// 綁定服務(wù)器地址和端口
if (bind(sockfd, (const struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
printf("Server running on port %d...\n", SERVER_PORT);
while (1) {
// 接收來自客戶端的數(shù)據(jù)
memset(buffer, 0, sizeof(buffer));
socklen_t client_len = sizeof(client_addr);
ssize_t message_size = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&client_addr, &client_len);
if (message_size < 0) {
perror("recvfrom failed");
exit(EXIT_FAILURE);
}
// 打印客戶端發(fā)送的數(shù)據(jù)
printf("Client message: %s\n", buffer);
// 向客戶端發(fā)送響應(yīng)
if (sendto(sockfd, buffer, message_size, 0, (struct sockaddr*)&client_addr, sizeof(client_addr)) < 0) {
perror("sendto failed");
exit(EXIT_FAILURE);
}
}
// 關(guān)閉套接字
close(sockfd);
return 0;
}
到了這里,關(guān)于網(wǎng)絡(luò)編程——UDP編程的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!