epoll服务端和客户端示例代码

epoll 服务端demo

#include <stdio.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>

#define MAX_EVENTS 20
#define BUFFER_LEN 512
#define IP_ADDR "192.168.1.3"
#define SERVER_PORT 8081

static int set_socket_non_blocking(int f) {
	int flags, s;
	flags = fcntl(f, F_GETFL, 0);
	if (-1 == flags) {
		perror("get fd status error");
		return -1;
	}
	flags |= O_NONBLOCK;
	s = fcntl(f, F_SETFL, flags);
	if (s == -1){
		perror("set fd status error");
		return -1;
	}
	return 0;
}

int main() {
	int listenfd = 0, epfd = 0;
	int result = 0;
	struct epoll_event ev, events[MAX_EVENTS];
	struct sockaddr_in server_addr = {0};

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (-1 == listenfd) {
		perror("open listen socket");
		return -1;
	}
	int on = 1;
	result = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if (-1 == result) {
		perror("set socket");
		return -1;
	}
	server_addr.sin_family = AF_INET;
	inet_aton(IP_ADDR, &(server_addr.sin_addr));
	server_addr.sin_port = htons(SERVER_PORT);
	result = bind(listenfd, (const struct sockaddr*)&server_addr, sizeof(server_addr));
	if (result == -1) {
		perror("bind socket");
		return -1;
	}
	result = set_socket_non_blocking(listenfd);
	if (result == -1) {
		printf("set socket non blocking failed\n");
		return -1;
	}
	result = listen(listenfd, 200);
	if (-1 == result) {
		perror("start listen");
		return -1;
	}

	epfd = epoll_create1(0);
	if (1 == epfd) {
		perror("create epoll instance");
		return -1;
	}
	ev.data.fd = listenfd;
	ev.events = EPOLLIN | EPOLLET;
	result = epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);
	if (-1 == result) {
		perror("set epoll ctl");
		return -1;
	}
	for (; ;) {
		int wait_count = 0;
		wait_count = epoll_wait(epfd, events, MAX_EVENTS, -1);

		for (int i = 0; i < wait_count; i++) {
			uint32_t event = events[i].events;
			char host_buf[NI_MAXHOST];
			char port_buf[NI_MAXSERV];

			int _result;
			if ((event & EPOLLERR) || (event & EPOLLHUP) || (!(event & EPOLLIN))) {
				printf("epoll has error\n");
				close(events[i].data.fd);
				continue;
			} else if (listenfd == events[i].data.fd) {
			    for (; ;) {
    				struct sockaddr in_addr = {0};
    				socklen_t in_addr_len = sizeof(in_addr);
    				int accp_fd = accept(listenfd, &in_addr, &in_addr_len);
    				if (-1 == accp_fd) {
    					perror("accept");
    					break;
    				}
    				_result = getnameinfo(&in_addr,	sizeof(in_addr),
    					host_buf, sizeof(host_buf) / sizeof(host_buf[0]),
    					port_buf, sizeof(port_buf) / sizeof(port_buf[0]),
    					NI_NUMERICHOST | NI_NUMERICSERV);
    				if (!_result) {
    					printf("new connection: host = %s, port = %s\n", host_buf, port_buf);
    				}
    				_result = set_socket_non_blocking(accp_fd);
    				if (-1 == _result) {
    					printf("set accept fd failed\n");
    					return 0;
    				}
    				ev.data.fd = accp_fd;
    				ev.events = EPOLLIN | EPOLLET;
    				_result = epoll_ctl(epfd, EPOLL_CTL_ADD, accp_fd, &ev);
    				if (-1 == _result) {
    					perror("epoll ctl");
    					return 0;
    				}
    			}
			    continue;
    		} else {
    			int done = 0;
    			for ( ; ; ) {
    				ssize_t result_len = 0;
    				char buf[BUFFER_LEN] = {0};
    				result_len = read(events[i].data.fd, buf, sizeof(buf) / sizeof(buf[0]));
    				if (-1 == result_len) {
    					if (EAGAIN != errno) {
    						perror("read data");
    						done = 1;
    					}
    					break;
    				} else if (!result_len) {
    					done = 1;
    					break;
    				}
    				if (strlen(buf) == 0)
    					continue;
    				for (int m = 0; buf[m] != '\0'; m++) {
    					buf[m] = toupper(buf[m]);
    				}
    				write(events[i].data.fd, buf, result_len);
    			}
    			if (done) {
    				printf("closed connection\n");
    				close(events[i].data.fd);
    			}
    		}
    	}
	}
	close(epfd);
	return 0;
}

epoll客户端demo

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>

#define BUFFER_SIZE 1024
#define IP_ADDR "192.168.1.2"
#define SERVER_PORT 8081

int sockfd = -1;
void sigctl(int sig) {
	if (sockfd != -1) {
		close(sockfd);
	}
	printf("bye, will exit ...\n");
	exit(0);
}

int main() {
	struct sockaddr_in st_clnsock;
	char msg[BUFFER_SIZE] = {0};
	int recv_size = 0;
	signal(SIGINT, sigctl);

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
    	printf("socket error: %s (errno: %d)\n", strerror(errno), errno);
    	exit(0);
    }
    memset(&st_clnsock, 0, sizeof(st_clnsock));
    st_clnsock.sin_family = AF_INET;
    if (inet_pton(AF_INET, IP_ADDR, &st_clnsock.sin_addr) <= 0) {
    	printf("inet pton error: %s (errno: %d)\n", strerror(errno), errno);
    	exit(0);
    }
    st_clnsock.sin_port = htons(SERVER_PORT);
    if (connect(sockfd, (struct sockaddr *)&st_clnsock, sizeof(st_clnsock)) < 0) {
    	printf("connect error: %s (errno: %d)\n", strerror(errno), errno);
    	exit(0);
    }
    while (1) {
    	memset(msg, 0, sizeof(msg));
    	fgets(msg, BUFFER_SIZE, stdin);
    	if (write(sockfd, msg, sizeof(msg)) < 0) {
    		printf("write error: %s (errno: %d)\n", strerror(errno), errno);
    		exit(0);
    	}
    	memset(msg, 0, sizeof(msg));
    	if ((recv_size = read(sockfd, msg, BUFFER_SIZE)) < 0) {
    		printf("read error: %s (errno: %d)\n", strerror(errno), errno);
    	} else if (recv_size == 0) {
    		printf("server closed\n");
    	} else {
    		printf("server return: %s\n", msg);
    	}
    }
    return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
下面是使用 C 语言实现 epoll客户端服务端代码示例服务端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/epoll.h> #define MAX_EVENTS 10 #define BUF_SIZE 256 int main(int argc, char* argv[]) { int port = atoi(argv[1]); // 获取端口号 int server_fd = socket(AF_INET, SOCK_STREAM, 0); if (server_fd < 0) { perror("socket() failed"); exit(EXIT_FAILURE); } struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(port); if (bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("bind() failed"); exit(EXIT_FAILURE); } if (listen(server_fd, 10) < 0) { perror("listen() failed"); exit(EXIT_FAILURE); } printf("Listening on port %d...\n", port); int epoll_fd = epoll_create1(0); if (epoll_fd < 0) { perror("epoll_create1() failed"); exit(EXIT_FAILURE); } struct epoll_event event, events[MAX_EVENTS]; event.data.fd = server_fd; event.events = EPOLLIN; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &event) < 0) { perror("epoll_ctl() failed"); exit(EXIT_FAILURE); } char buf[BUF_SIZE]; while (1) { int ready = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (ready < 0) { perror("epoll_wait() failed"); exit(EXIT_FAILURE); } for (int i = 0; i < ready; i++) { if (events[i].data.fd == server_fd) { struct sockaddr_in client_addr; socklen_t client_len = sizeof(client_addr); int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len); if (client_fd < 0) { perror("accept() failed"); exit(EXIT_FAILURE); } printf("Client connected: %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); event.data.fd = client_fd; event.events = EPOLLIN; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event) < 0) { perror("epoll_ctl() failed"); exit(EXIT_FAILURE); } } else { int client_fd = events[i].data.fd; ssize_t count = recv(client_fd, buf, sizeof(buf), 0); if (count < 0) { perror("recv() failed"); exit(EXIT_FAILURE); } else if (count == 0) { printf("Client disconnected\n"); close(client_fd); } else { printf("Received %ld bytes from client: %.*s\n", count, (int)count, buf); send(client_fd, buf, count, 0); } } } } close(server_fd); return 0; } ``` 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <sys/epoll.h> #define MAX_EVENTS 10 #define BUF_SIZE 256 int main(int argc, char* argv[]) { const char* server_ip = argv[1]; int port = atoi(argv[2]); int client_fd = socket(AF_INET, SOCK_STREAM, 0); if (client_fd < 0) { perror("socket() failed"); exit(EXIT_FAILURE); } struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(server_ip); server_addr.sin_port = htons(port); if (connect(client_fd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) { perror("connect() failed"); exit(EXIT_FAILURE); } printf("Connected to server: %s:%d\n", server_ip, port); int epoll_fd = epoll_create1(0); if (epoll_fd < 0) { perror("epoll_create1() failed"); exit(EXIT_FAILURE); } struct epoll_event event, events[MAX_EVENTS]; event.data.fd = client_fd; event.events = EPOLLIN; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &event) < 0) { perror("epoll_ctl() failed"); exit(EXIT_FAILURE); } char buf[BUF_SIZE]; while (1) { int ready = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (ready < 0) { perror("epoll_wait() failed"); exit(EXIT_FAILURE); } for (int i = 0; i < ready; i++) { if (events[i].data.fd == client_fd) { ssize_t count = recv(client_fd, buf, sizeof(buf), 0); if (count < 0) { perror("recv() failed"); exit(EXIT_FAILURE); } else if (count == 0) { printf("Server disconnected\n"); close(client_fd); } else { printf("Received %ld bytes from server: %.*s\n", count, (int)count, buf); } } else { fgets(buf, sizeof(buf), stdin); ssize_t count = send(client_fd, buf, strlen(buf), 0); if (count < 0) { perror("send() failed"); exit(EXIT_FAILURE); } } } } close(client_fd); return 0; } ``` 在这个示例中,我们使用了 epoll 来实现并发处理多个客户端的连接。服务器会等待客户端连接,一旦有客户端连接,就将其加入 epoll 等待队列中。同时,客户端也会连接服务器,并将其套接字加入 epoll 等待队列中。当客户端服务器有消息到来时,都会触发 epoll_wait() 函数。然后,我们可以使用 recv() 和 send() 函数来接收和发送消息。 请注意,这只是一个示例代码,可能还需要进行更多的错误处理和安全检查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

codears

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值