#include <asm-generic/socket.h>
#include <cctype>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <netinet/in.h>
#include <strings.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <unistd.h>
static const uint16_t kPort = 3366;
static const char *kIpStr = "192.168.3.20";
int main() {
char buffer[BUFSIZ];
int listenFd = socket(AF_INET, SOCK_STREAM, 0);
if (listenFd < 0) {
perror("create socket error.]n");
exit(-1);
}
int resuse = 1;
setsockopt(listenFd, SOL_SOCKET, SO_REUSEADDR, &resuse, sizeof(resuse));
sockaddr_in s_addr;
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(kPort);
inet_pton(AF_INET, kIpStr, &s_addr.sin_addr);
int ret = bind(listenFd, (const struct sockaddr *)&s_addr, sizeof(s_addr));
if (ret < 0) {
perror("bind socket error.\n");
exit(-1);
}
listen(listenFd, 125);
// 创建epoll
int epfd = epoll_create(10);
if (epfd < 0) {
perror("create epoll error.\n");
exit(-1);
}
// 添加epoll监听文件描述符
epoll_event event;
event.events = EPOLLIN;
event.data.fd = listenFd;
ret = epoll_ctl(epfd, EPOLL_CTL_ADD, listenFd, &event);
if (ret < 0) {
perror("epoll_ctl error.\n");
exit(-1);
}
epoll_event ep_arr[10];
while (1) {
// ep_arr:存放监听返回的文件描述符数组,传出参数
// 10:数组的长度
//-1:阻塞直到有事件发生
int nready = epoll_wait(epfd, ep_arr, 10, -1);
if (nready == -1) {
perror("epoll_watit error.\n");
exit(-1);
}
for (int i = 0; i < nready; ++i) {
if (!(ep_arr[i].events & EPOLLIN)) {
continue;
}
if (ep_arr[i].data.fd == listenFd) {
sockaddr_in c_addr;
bzero(&c_addr, sizeof(c_addr));
socklen_t c_addr_len = sizeof(c_addr);
int connfd = accept(listenFd, (struct sockaddr *)&c_addr, &c_addr_len);
if (connfd < 0) {
perror("accept error.\n");
continue;
}
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = connfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
} else {
int connfd = ep_arr[i].data.fd;
memset(buffer, 0, sizeof(buffer));
int num_read = read(connfd, buffer, sizeof(buffer));
if (num_read < 0) {
perror("read error\n");
} else if (num_read == 0) {
// 连接关闭,从epoll中移除
epoll_ctl(epfd, EPOLL_CTL_DEL, connfd, nullptr);
close(connfd);
printf("scoket close.\n");
} else {
printf("server receive:%s\n", buffer);
for (int i = 0; i < num_read; ++i) {
buffer[i] = toupper(buffer[i]);
}
write(connfd, buffer, num_read);
printf("response success.\n");
}
}
}
}
close(listenFd);
close(epfd);
return 0;
}
Linux网络编程:epoll
猜你喜欢
转载自blog.csdn.net/xiwenhec/article/details/129430387
今日推荐
周排行