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