#include <cctype>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <netinet/in.h>
#include <strings.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <cstring>
#include <poll.h>
#include <unistd.h>
static const uint16_t kServerPort = 3366;
static const char *kIpStr = "192.168.3.20";
static const int kMaxOpen = 1024;
int main() {
char buffer[BUFSIZ];
bzero(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));
struct sockaddr_in s_addr;
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_port = htons(kServerPort);
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("sockt bind error.\n");
exit(-1);
}
listen(listenFd, 125);
// 定义一个用于存放监听socket文件描述符的数组
struct pollfd cFdSet[kMaxOpen];
cFdSet[0].fd = listenFd;
cFdSet[0].events = POLLIN; // 设置读监听事件
for (int i = 1; i < kMaxOpen; ++i) {
cFdSet[i].fd = -1;
}
int lastIndex = 0;
while (1) {
// 参数1:用于监听的pollfd数组
// 参数2:这里需要注意的是由于cFdSet是一个数组,当有fd被移出时,并不会自动合并前移
// 所以这里的值应该是cFdSet数组中最后一个元素的下标+1;
// 参数3:负数表示一直阻塞,直到有事件发生;
// 0表示:无论是否有事件发生,都立即返回;
// 大于0:阻塞到指定的毫秒数返回
int ready_num = poll(cFdSet, lastIndex + 1, -1);
// 检测是否有监听文件描述符上发生事件
if (cFdSet[0].revents & POLLIN) {
struct sockaddr_in c_addr;
bzero(&s_addr, sizeof(s_addr));
socklen_t addrLen = sizeof(s_addr);
int connFd = accept(listenFd, (struct sockaddr *)&s_addr, &addrLen);
if (connFd < 0) {
perror("accept client socket error.\n");
exit(-1);
}
int i = 1;
for (; i < kMaxOpen; ++i) {
if (cFdSet[i].fd == -1) {
cFdSet[i].fd = connFd;
cFdSet[i].events = POLLIN;
if (i > lastIndex) {
lastIndex = i;
}
break;
}
}
if (i == kMaxOpen) {
printf("too many client connect.\n");
}
if (--ready_num == 0) {
continue;
}
}
for (int i = 1; i < lastIndex + 1; ++i) {
if (cFdSet[i].revents & POLLIN) {
int read_num = read(cFdSet[i].fd, buffer, sizeof(buffer));
if (read_num < 0) {
if (errno == ECONNRESET) {
close(cFdSet[i].fd);
cFdSet[i].fd = -1;
} else {
perror("socket read error.\n");
}
} else if (read_num == 0) {
close(cFdSet[i].fd);
cFdSet[i].fd = -1;
} else {
printf("server receive:%s\n", buffer);
for (int i = 0; i < read_num; ++i) {
buffer[i] = toupper(buffer[i]);
}
write(cFdSet[i].fd, buffer, read_num);
}
}
}
}
close(listenFd);
return 0;
}
linux网络编程:poll
最新推荐文章于 2024-08-23 08:57:21 发布