Libevent UDP開發指南

UDP 與 TCP 的核心區別

  1. 無連接:不需要建立/維護連接

  2. 不可靠:不保證數據包順序和到達

  3. 高效:頭部開銷小,沒有連接管理負擔

  4. 支持廣播/多播:可以向多個目標同時發送數據

一、基礎UDP服務器實現

1. 創建 UDP 套接字

#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>
#include <arpa/inet.h>int create_udp_socket(int port) {int fd = socket(AF_INET, SOCK_DGRAM, 0);if (fd < 0) {perror("socket");return -1;}struct sockaddr_in sin;memset(&sin, 0, sizeof(sin));sin.sin_family = AF_INET;sin.sin_port = htons(port);sin.sin_addr.s_addr = htonl(INADDR_ANY);if (bind(fd, (struct sockaddr*)&sin, sizeof(sin)) < 0) {perror("bind");close(fd);return -1;}// 設置非阻塞evutil_make_socket_nonblocking(fd);return fd;
}

2. UDP 事件處理

void udp_read_cb(evutil_socket_t fd, short events, void *arg) {struct sockaddr_in client_addr;socklen_t addr_len = sizeof(client_addr);char buf[1500]; // 標準MTU大小ssize_t n;while ((n = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr*)&client_addr, &addr_len)) > 0) {// 處理接收到的數據printf("Received %zd bytes from %s:%d\n", n, inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));// 簡單回顯sendto(fd, buf, n, 0, (struct sockaddr*)&client_addr, addr_len);}if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {perror("recvfrom");}
}int main() {int udp_fd = create_udp_socket(8080);if (udp_fd < 0) return 1;struct event_base *base = event_base_new();struct event *udp_event = event_new(base, udp_fd, EV_READ | EV_PERSIST, udp_read_cb, NULL);event_add(udp_event, NULL);printf("UDP server started on port 8080\n");event_base_dispatch(base);event_free(udp_event);close(udp_fd);event_base_free(base);return 0;
}

3. UDP 服務器示例代碼

#include <event2/event.h>
#include <event2/bufferevent.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <time.h>#define MAX_CLIENTS 10000
#define MAX_PACKET_SIZE 1500struct udp_client {struct sockaddr_in addr;time_t last_active;
};struct udp_server {struct event_base *base;int sockfd;struct event *ev;struct udp_client clients[MAX_CLIENTS];
};void udp_read_cb(evutil_socket_t fd, short events, void *arg) {struct udp_server *server = arg;char buf[MAX_PACKET_SIZE];struct sockaddr_in client_addr;socklen_t addr_len = sizeof(client_addr);ssize_t n = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr*)&client_addr, &addr_len);if (n <= 0) return;// 查找或創建客戶端記錄struct udp_client *client = NULL;for (int i = 0; i < MAX_CLIENTS; i++) {if (memcmp(&server->clients[i].addr, &client_addr, addr_len) == 0) {client = &server->clients[i];break;}}if (!client) {// 查找空閑槽位for (int i = 0; i < MAX_CLIENTS; i++) {if (server->clients[i].last_active == 0) {client = &server->clients[i];memcpy(&client->addr, &client_addr, addr_len);break;}}}if (client) {client->last_active = time(NULL);// 業務處理printf("Received %zd bytes from %s:%d\n", n, inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));// 回顯sendto(fd, buf, n, 0, (struct sockaddr*)&client_addr, addr_len);} else {printf("Client limit reached, dropping packet\n");}
}struct udp_server* udp_server_create(int port) {struct udp_server *server = malloc(sizeof(struct udp_server));memset(server, 0, sizeof(*server));// 創建socketserver->sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (server->sockfd < 0) {perror("socket");free(server);return NULL;}// 綁定地址struct sockaddr_in sin;memset(&sin, 0, sizeof(sin));sin.sin_family = AF_INET;sin.sin_port = htons(port);sin.sin_addr.s_addr = htonl(INADDR_ANY);if (bind(server->sockfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) {perror("bind");close(server->sockfd);free(server);return NULL;}// 設置非阻塞evutil_make_socket_nonblocking(server->sockfd);// 創建事件基server->base = event_base_new();if (!server->base) {close(server->sockfd);free(server);return NULL;}// 創建事件server->ev = event_new(server->base, server->sockfd, EV_READ | EV_PERSIST, udp_read_cb, server);event_add(server->ev, NULL);return server;
}void udp_server_run(struct udp_server *server) {event_base_dispatch(server->base);
}void udp_server_free(struct udp_server *server) {if (!server) return;if (server->ev) event_free(server->ev);if (server->base) event_base_free(server->base);if (server->sockfd > 0) close(server->sockfd);free(server);
}int main() {struct udp_server *server = udp_server_create(8080);if (!server) return 1;printf("UDP server started on port 8080\n");udp_server_run(server);udp_server_free(server);return 0;
}

4. UDP 客戶器示例代碼 

#include <event2/event.h>
#include <event2/dns.h>
#include <event2/bufferevent.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>struct udp_client {struct event_base *base;struct evdns_base *dns;int sockfd;struct sockaddr_in server_addr;int connected;pthread_mutex_t lock;
};void udp_read_cb(evutil_socket_t fd, short events, void *arg) {struct udp_client *client = arg;char buf[1500];struct sockaddr_in from_addr;socklen_t addr_len = sizeof(from_addr);ssize_t n = recvfrom(fd, buf, sizeof(buf), 0,(struct sockaddr*)&from_addr, &addr_len);if (n > 0) {buf[n] = '\0';pthread_mutex_lock(&clie

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76797.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76797.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76797.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于阿里云可觀測產品構建企業級告警體系的通用路徑與最佳實踐

前言 1.1 日常生活中的告警 任何連續穩定運行的生產系統都離不開有效的監控與報警機制。通過監控&#xff0c;我們可以實時掌握系統和業務的運行狀態&#xff1b;而報警則幫助我們及時發現并響應監控指標及業務中的異常情況。 在日常生活中&#xff0c;我們也經常遇到各種各樣…

智能多媒體處理流水線——基于虎躍辦公API的自動化解決方案

在內容爆炸的時代&#xff0c;多媒體文件處理&#xff08;圖片壓縮、視頻轉碼、音頻降噪&#xff09;已成為內容生產者的日常挑戰。本文將演示如何基于虎躍辦公的多媒體處理API&#xff0c;構建自動化處理流水線&#xff0c;實現&#xff1a; 批量文件智能分類格式自動轉換質量…

01-STM32(介紹、工具準備、新建工程)p1-4

文章目錄 工具準備和介紹硬件設備stm32簡介和arm簡介stm32簡介STM32命名規則STM32選型STM32F103C8T6最小系統板引腳定義STM32啟動配置STM32最小系統電路ARM簡介 軟件安裝注冊器件支持包安裝ST-LINK驅動安裝USB轉串口驅動 新建工程創建stm32工程STM32工程編譯和下載型號分類及縮…

【ABAP】REST/HTTP技術(一)

1、概念 1.1、SAP 如何提供 Http Service 如果要將 SAP 應用程序服務器 &#xff08;application server&#xff09;作為 http 服務提供者&#xff0c;需要定義一個類&#xff0c;這個類必須實現 IF_HTTP_EXTENSION 接口。IF_HTTP_EXTENSION 接口只有一個方法 HANDLE_REQUEST。…

[實戰] linux驅動框架與驅動開發實戰

linux驅動框架與驅動開發實戰 Linux驅動框架與驅動開發實戰一、Linux驅動框架概述1.1 Linux驅動的分類1.2 Linux驅動的基本框架 二、Linux驅動關鍵API詳解2.1 模塊相關API2.2 字符設備驅動API2.3 內存管理API2.4 中斷處理API2.5 PCI設備驅動API 三、Xilinx XDMA驅動開發詳解3.1…

1. hadoop 集群的常用命令

1.上傳文件 1)hadoop fs -put words.txt /path/to/input/ 2)hdfs dfs -put words.txt /path/wc/input/ 2.獲取hdfs中的文件 hadoop fs -get /path/wc/input/words.txt 3.合并下載多個文件 hadoop fs -getmerge /path/wc/input/words.txt /path/wc/input/words2.txt 4.查…

Keepalived+LVS+nginx高可用架構

注明&#xff1a;所有軟件已經下載好&#xff0c;防火墻和SELinux已經全部關閉 一.搭建NFS 1.服務端 1.創建文件 [rootnfs ~]# mkdir -p /nfs/data 2、修改權限 [rootnfs ~]# chmod orw /nfs/data 3、寫配置文件 [rootnfs ~]# cat /etc/exports /nfs/data 192.168.111.118(r…

深度學習處理文本(13)

我們使用基于GRU的編碼器和解碼器來在Keras中實現這一方法。選擇GRU而不是LSTM&#xff0c;會讓事情變得簡單一些&#xff0c;因為GRU只有一個狀態向量&#xff0c;而LSTM有多個狀態向量。首先是編碼器&#xff0c;如代碼清單11-28所示。 代碼清單11-28 基于GRU的編碼器 fro…

HashMap 底層原理詳解

1. 核心數據結構 JDK 1.7 及之前&#xff1a;數組 鏈表 JDK 1.8 及之后&#xff1a;數組 鏈表/紅黑樹&#xff08;鏈表長度 ≥8 時轉紅黑樹&#xff0c;≤6 時退化為鏈表&#xff09; // JDK 1.8 的 Node 定義&#xff08;鏈表節點&#xff09; static class Node<K,V&g…

使用MySQL時出現 Ignoring query to other database 錯誤

Ignoring query to other database 錯誤 當在遠程連接軟件中輸入MySQL命令出現該錯誤 導致錯誤原因是&#xff1a;登錄mysql時賬戶名沒有加上u 如果出現該錯誤&#xff0c;退出mysql&#xff0c;重新輸入正確格式進入即可&#xff01;

哈爾濱工業大學:大模型時代的具身智能

大家好&#xff0c;我是櫻木。 機器人在工業領域&#xff0c;已經逐漸成熟。具身容易&#xff0c;智能難。 機器人-》智能機器人&#xff0c;需要自主能力&#xff0c;加上通用能力。 智能機器人-》人類&#xff0c;這個階段就太有想象空間了。而最受關注的-類人機器人。 如何…

Javascript代碼壓縮混淆工具terser詳解

原始的JavaScript代碼在正式的服務器上,如果沒有進行壓縮,混淆,不僅加載速度比較慢,而且還存在安全和性能問題. 因此現在需要進行壓縮,混淆處理. 處理方案簡單描述一下: 1. 使用 terser 工具進行 安裝 terser工具: # npm 安裝 npm install terser --save-dev# 或使用 yarn 安…

Java String 常用方法詳解

目錄 一、獲取字符串信息(一)獲取字符串長度(二)獲取指定索引處的字符(三)獲取子字符串二、字符串比較(一)比較字符串內容(二)忽略大小寫比較三、字符串轉換(一)轉換為大寫(二)轉換為小寫四、字符串查找(一)查找子字符串的位置(二)從指定位置開始查找五、字符…

Linux驅動開發練習案例

1 開發目標 1.1 架構圖 操作系統&#xff1a;基于Linux5.10.10源碼和STM32MP157開發板&#xff0c;完成tf-a(FSBL)、u-boot(SSBL)、uImage、dtbs的裁剪&#xff1b; 驅動層&#xff1a;為每個外設配置DTS并且單獨封裝外設驅動模塊。其中電壓ADC測試&#xff0c;采用linux內核…

leetcode-代碼隨想錄-哈希表-贖金信

題目 題目鏈接&#xff1a;383. 贖金信 - 力扣&#xff08;LeetCode&#xff09; 給你兩個字符串&#xff1a;ransomNote 和 magazine &#xff0c;判斷 ransomNote 能不能由 magazine 里面的字符構成。 如果可以&#xff0c;返回 true &#xff1b;否則返回 false 。 maga…

精品可編輯PPT | “新基建”在數字化智慧高速公路中的支撐應用方案智慧建筑智慧交通解決方案施工行業解決方案

本文詳細闡述了“新基建”在數字化智慧高速公路中的支撐應用方案&#xff0c;從政策背景出發&#xff0c;指出國家在交通領域的一系列發展規劃和指導意見&#xff0c;強調了智慧交通建設的重要性。分析了當前高速公路存在的問題&#xff0c;如基礎感知設施不足、協同水平低、服…

C語言求3到100之間的素數

一、代碼展示 二、運行結果 三、感悟思考 注意: 這個題思路他是一個試除法的一個思路 先進入一個for循環 遍歷3到100之間的數字 第二個for循環則是 判斷他不是素數 那么就直接退出 這里用break 是素數就打印出來 在第一個for循環內 第二個for循環外

英語—四級CET4考試—蒙猜篇—匹配題

蒙猜方法一 匹配題的做題&#xff1a; 方法一&#xff1a; 首先&#xff0c;什么都不想&#xff0c;把問題中ing形式的&#xff0c;大寫字母的&#xff0c;人名&#xff0c;地名&#xff0c;最后幾個依次框起來。 然后&#xff0c;比如46題&#xff0c;口里默念meaningful lif…

股票日數據使用_未復權日數據生成前復權日周月季年數據

目錄 前置&#xff1a; 準備 代碼&#xff1a;數據庫交互部分 代碼&#xff1a;生成前復權 日、周、月、季、年數據 前置&#xff1a; 1 未復權日數據獲取&#xff0c;請查看 https://blog.csdn.net/m0_37967652/article/details/146435589 數據庫使用PostgreSQL。更新日…

系統與網絡安全------Windows系統安全(6)

資料整理于網絡資料、書本資料、AI&#xff0c;僅供個人學習參考。 共享文件夾 發布共享文件夾 Windows共享概述 微軟公司推出的網絡文件/打印機服務系統 可以將一臺主機的資源發布給其他主機共有 共享訪問的優點 方便、快捷相比光盤 U盤不易受文件大小限制 可以實現訪問…