Ai
1 Star 0 Fork 0

Shawy/2023Linux

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
pollServer.hpp 4.62 KB
一键复制 编辑 原始数据 按行查看 历史
Shawy 提交于 2023-10-04 16:03 +08:00 . PollServer
#ifndef __POLL_SVR_H__
#define __POLL_SVR_H__
#include <iostream>
#include <cerrno>
#include <cstring>
#include <string>
#include <sys/poll.h>
#include <sys/time.h>
#include "Sock.hpp"
#include "Log.hpp"
#define FD_NONE -1
class PollServer
{
public:
PollServer(const uint16_t &port = 8080, const int &nfds = 100)
: _port(port), _nfds(nfds)
{
_listensock = Sock::Socket();
Sock::Bind(_listensock, _port);
Sock::Listen(_listensock);
logMessage(DEBUG, "%s", "create socket success");
// 为数组分配空间并初始化
_fds = new struct pollfd[_nfds];
for (int i = 0; i < _nfds; i++)
{
_fds[i].fd = FD_NONE;
_fds[i].events = _fds[i].revents = 0;
}
// 规定第一个元素标识套接字
_fds[0].fd = _listensock;
_fds[0].events = POLLIN;
_timeout = -1;
}
void Start()
{
while (true)
{
PrintForDebug();
int n = poll(_fds, _nfds, _timeout);
switch (n)
{
case 0:
logMessage(DEBUG, "timeout...");
break;
case -1:
logMessage(DEBUG, "select error: [%d : %s]", errno, strerror(errno));
break;
default:
logMessage(DEBUG, "get a new link event!");
HandlerEvent();
break;
}
}
}
~PollServer()
{
if (_listensock >= 0)
close(_listensock);
// 释放数组空间
if (_fds)
delete[] _fds;
}
private:
void HandlerEvent()
{
for (int i = 0; i < _nfds; i++)
{
// 过滤
if (_fds[i].fd == FD_NONE)
continue;
// 检查数组中的文件描述符是否就绪
if (_fds[i].revents & POLLIN)
{
if (_fds[i].fd == _listensock)
{
logMessage(DEBUG, "accept a new link, fd[%d]", _fds[i].fd);
Accepter();
}
else
{
logMessage(DEBUG, "get a new IO event, fd[%d]", _fds[i].fd);
Recver(i);
}
}
}
}
// 处理新连接
void Accepter()
{
uint16_t client_port = 0;
std::string client_ip;
// 获取新连接
int sock = Sock::Accept(_listensock, &client_ip, &client_port);
if (sock < 0)
{
logMessage(WARNING, "accept error");
return;
}
logMessage(DEBUG, "get a new link success...[%s : %d] : %d", client_ip.c_str(), client_port, sock);
// 处理连接事件
int pos = 1;
for (; pos < _nfds; pos++)
{
if (_fds[pos].fd == FD_NONE)
break;
}
if (pos == _nfds) // 满
{
// 扩容
struct pollfd *new_fds;
int new_nfds = _nfds * 2;
new_fds = new struct pollfd[new_nfds];
memcpy(new_fds, _fds, sizeof(struct pollfd) * _nfds);
delete[] _fds;
_fds = new_fds;
}
else // 未满
{
_fds[pos].fd = sock;
_fds[pos].events = POLLIN;
}
}
// 处理文件读取
void Recver(int pos)
{
char buffer[1024];
int n = recv(_fds[pos].fd, buffer, sizeof(buffer) - 1, 0);
if (n > 0)
{
buffer[n] = '\0';
std::cout << "client[" << _fds[pos].fd << "]>>> " << buffer << std::endl;
}
else if (n == 0) // 对端关闭连接
{
logMessage(DEBUG, "client[%d] quit, me too...", _fds[pos].fd);
close(_fds[pos].fd);
_fds[pos].fd = FD_NONE;
_fds[pos].events = 0;
}
else // 错误
{
logMessage(WARNING, "sock[%d] recv/read error, code:%d: %s", _fds[pos].fd, errno, strerror(errno));
close(_fds[pos].fd);
_fds[pos].fd = FD_NONE;
_fds[pos].events = 0;
}
}
// 打印目前所有被监视的文件描述符
void PrintForDebug()
{
std::cout << "_fd_array[]: ";
for (int i = 0; i < _nfds; i++)
{
if (_fds[i].fd == FD_NONE)
continue;
std::cout << _fds[i].fd << " ";
}
std::cout << std::endl;
std::cout << "-------------------" << std::endl;
}
private:
uint16_t _port;
int _listensock;
struct pollfd *_fds; // 数组指针
nfds_t _nfds; // 数组大小
int _timeout;
};
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/shawyxy/2023-linux.git
git@gitee.com:shawyxy/2023-linux.git
shawyxy
2023-linux
2023Linux
main

搜索帮助