
udp epoll tcp epoll使用
发布日期:2021-05-10 14:45:48
浏览次数:29
分类:精选文章
本文共 4038 字,大约阅读时间需要 13 分钟。
udp epoll
#define _GNU_SOURCE 1
#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <errno.h> #include <sys/timerfd.h> #include <sys/epoll.h> #include <sys/types.h> #include <netinet/in.h> #include <unistd.h> #define ADDR INADDR_LOOPBACK #define PORT 34567 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #define SAVE_ERRNO(block) do { int errno_ = errno; { block; } errno = errno_; } while (0) typedef struct { int fd; unsigned int readable:1; unsigned int writable:1; } peer_t; static int tmfd = -1; static int epfd = -1; static int npeers; static unsigned long bytes_read; static unsigned long bytes_written; static void do_report(void) { printf( "=====================\n" "%lu bytes read\n" "%lu bytes written\n", bytes_read, bytes_written); bytes_read = 0; bytes_written = 0; } static int do_close(int fd) { int r; do r = close(fd); while (r == -1 && errno == EINTR); return r; } static int add_fd(int fd, void *arg, int events) { struct epoll_event ee = { .data.ptr = arg, .events = events | EPOLLET }; return epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ee); } static int make_sock_fd(unsigned short port) { struct sockaddr_in sin; int sockfd; if ((sockfd = socket(AF_INET, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0)) == -1) return -1; memset(&sin, 0, sizeof sin); sin.sin_addr.s_addr = htonl(ADDR); sin.sin_port = htons(port); sin.sin_family = AF_INET; if (bind(sockfd, (struct sockaddr *) &sin, sizeof sin) == -1) return -1; return sockfd; } static int make_timer_fd(unsigned int ms) { struct itimerspec its; if ((tmfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) == -1) return -1; #define SET_TS(ts, ms) ((ts)->tv_sec = (ms) / 1000, (ts)->tv_nsec = ((ms) % 1000) * 1e6) SET_TS(&its.it_interval, ms); SET_TS(&its.it_value, ms); if (timerfd_settime(tmfd, 0, &its, NULL)) { SAVE_ERRNO(do_close(tmfd)); return -1; } return tmfd; } static int do_recv(int fd) { char buf[1024]; ssize_t r; do r = read(fd, buf, sizeof buf); while (r == -1 && errno == EINTR); if (r > 0) bytes_read += r; return r; } static int do_send(int fd, const void *data, size_t size) { struct sockaddr_in sin; ssize_t r; static int port = PORT; port = PORT + (((port - PORT) + 1) % npeers); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(ADDR); sin.sin_port = htons(port); do r = sendto(fd, data, size, 0, (struct sockaddr *) &sin, sizeof sin); while (r == -1 && errno == EINTR); if (r > 0) bytes_written += r; return r; } static int do_epoll(void) { struct epoll_event out[1024]; peer_t *peer; int i, n, r; int events; int fd; do n = epoll_wait(epfd, out, ARRAY_SIZE(out), -1); while (n == -1 && errno == EINTR); if (n == -1) return -1; for (i = 0; i < n; i++) { events = out[i].events; peer = out[i].data.ptr; fd = peer->fd; if (events & ~(EPOLLIN|EPOLLOUT)) return -1; if (fd == tmfd) { char buf[8]; read(fd, buf, 8); do_report(); continue; } if (peer->readable && (events & EPOLLIN)) { if ((r = do_recv(fd)) == -1) return -1; else peer->readable = 0, peer->writable = 1; } if (peer->writable && (events & EPOLLOUT)) { const char reply[] = "PING"; if ((r = do_send(fd, reply, sizeof(reply) - 1)) == -1) return -1; else peer->readable = 1, peer->writable = 0; } } return 0; } int main(int argc, char **argv) { peer_t *peers; peer_t tmp; int i, r; (void) argc; if (argv[1] == NULL || (npeers = atoi(argv[1])) == 0) npeers = 100; if ((epfd = epoll_create1(EPOLL_CLOEXEC)) == -1) { perror("make_epoll_fd"); exit(1); } if ((tmfd = make_timer_fd(2000)) == -1) { perror("make_timer_fd"); exit(1); } tmp.fd = tmfd; if (add_fd(tmfd, &tmp, EPOLLIN)) { perror("add_fd"); exit(1); } if ((peers = calloc(npeers, sizeof(peers[0]))) == NULL) { perror("malloc"); exit(1); } for (i = 0; i < npeers; i++) { peers[i].readable = 0; peers[i].writable = 1; if ((peers[i].fd = make_sock_fd(PORT + i)) == -1) perror("make_sock_fd"); else if (add_fd(peers[i].fd, &peers[i], EPOLLIN|EPOLLOUT)) perror("add_fd"); } while ((r = do_epoll()) == 0) /* nop */ ; if (r == -1) { perror("do_epoll"); exit(1); } return 0;
}
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2025年04月17日 04时14分09秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
strlen sizeof 快
2021-05-10
【Java-27】Java常见错误记录
2021-05-10
andriod 开发错误记录
2021-05-10
生成树协议(二)
2021-05-10
创建一个简单的SpingBoot项目,并且部署到linux上运行
2021-05-10
mysql8.0及以上在my.cnf设置sql_mode之后mysql无法启动
2021-05-10
C语言编译错误列表
2021-05-10
万倍币传说不再,价值回归
2021-05-10
看明白这两种情况,才敢说自己懂跨链! | 喵懂区块链24期
2021-05-10
6大亮点抢先看!Facebook加密货币项目Libra白皮书解读
2021-05-10
数字印钞界迎来重磅精英机构,普通人还有翻身机会吗? | 加密货币与阶层穿越...
2021-05-10
张一鸣:创业7年,我经历的5件事
2021-05-10
SQL基础语法
2021-05-10
Python3 日期和时间
2021-05-10
JavaScript实现表格排序
2021-05-10
vue散碎知识点学习
2021-05-10
git拉取远程指定分支代码
2021-05-10
C语言--C语言总结大纲
2021-05-10
轻松理解前后端分离(通俗易懂)
2021-05-10
JavaFX官方文档
2021-05-10