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;
}

相关推荐

  1. epoll服务客户示例代码

    2024-06-18 22:42:06       31 阅读
  2. Linux下网络编程-简易Epll服务器客户

    2024-06-18 22:42:06       35 阅读
  3. udp(无连接)客户服务代码

    2024-06-18 22:42:06       69 阅读
  4. GRPC服务客户DEMO

    2024-06-18 22:42:06       43 阅读
  5. Qt建立服务客户

    2024-06-18 22:42:06       36 阅读
  6. 一个简单的UDP客户服务的完整C++示例

    2024-06-18 22:42:06       37 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-18 22:42:06       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-18 22:42:06       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-18 22:42:06       87 阅读
  4. Python语言-面向对象

    2024-06-18 22:42:06       96 阅读

热门阅读

  1. 单例设计模式双重检查的作用

    2024-06-18 22:42:06       26 阅读
  2. MyBatis 自定义映射 ResultMap:一对多映射关系处理

    2024-06-18 22:42:06       31 阅读
  3. 删除名为 `XXXX` 的 conda 环境的命令

    2024-06-18 22:42:06       29 阅读
  4. LVGL:

    LVGL:

    2024-06-18 22:42:06      28 阅读
  5. NLP - word2vec详解

    2024-06-18 22:42:06       27 阅读
  6. 自动抓取服务器功耗

    2024-06-18 22:42:06       24 阅读
  7. MySQL触发器基本结构

    2024-06-18 22:42:06       32 阅读
  8. 通过摄像头检测步频

    2024-06-18 22:42:06       29 阅读
  9. 通用与垂直,难以预测的胜负之争。

    2024-06-18 22:42:06       31 阅读