部分代码复用select的代码
主代码如下:
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <poll.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <vector>
#include <iostream>
#include "socket.h"
typedef std::vector<struct pollfd> POLL_FD_VECTOR;
int AcceptConnect(POLL_FD_VECTOR &PollFdVector)
{
struct sockaddr_in stPeerAddr;
struct pollfd stPollFd;
socklen_t SocketLen = 0;
int AcceptFd = -1;
//为什么是第0号元素?
//0号元素是server的 listen socket,用来侦听客户端连接
if (PollFdVector[0].revents & POLLIN)
{
SocketLen = sizeof(stPeerAddr);
AcceptFd = accept4(PollFdVector[0].fd, (struct sockaddr*)&stPeerAddr,
&SocketLen, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (AcceptFd == -1)
{
//进程打开描述符到达上限处理
if (errno == EMFILE)
{
ERR_INFO_S stErrInfo;
stErrInfo.enErrType = ERR_EMFILE;
stErrInfo.pvUserData = (void *)&AcceptFd;
ProcessErr(stErrInfo);
continue;
}
SHOW_ERR("\n");
goto EXIT;
}
else
{
// 连接成功
SHOW_SOCKADDR_INFO(stPeerAddr);
//将会话socket加入侦听序列
stPollFd.fd = AcceptFd;
stPollFd.events = POLLIN;
stPollFd.revents = 0;
PollFdVector.push_back(stPollFd);
goto EXIT;
}
}
else
{
return FAILURE;
}
EXIT:
return SUCCESS;
}
int ReadData(POLL_FD_VECTOR &PollFdVector)
{
int s32Ret = -1;
int AcceptFd = -1;
//从1号元素开始轮询已经连接套接字事件,
for (POLL_FD_VECTOR::iterator it=PollFdVector.begin()+1;
it != PollFdVector.end(); ++it)
{
if (it->revents & POLLIN)
{
AcceptFd = it->fd;
char buf[NORMAL_BUF_LEN] = {0};
s32Ret = read(AcceptFd, buf, NORMAL_BUF_LEN);
if (s32Ret == -1)
{
SHOW_ERR("\n");
}
if (s32Ret == 0)
{
SHOW_ERR("client close!\n");
it = PollFdVector.erase(it);
--it;
close(AcceptFd);
continue;
}
std::cout<<buf;
write(AcceptFd, buf, strlen(buf));
}
}
return SUCCESS;
}
int main(void)
{
InitErrDeal();
int s32Ret = FAILURE;
int s32ServerFd = -1;
s32Ret = InitServerSocket(s32ServerFd);
{
SHOW_ERR("\n");
}
//将监听socket加入侦听序列
struct pollfd stPollFd;
stPollFd.fd = s32ServerFd;
//events保存用户关注的事件标识
//revents保存内核侦听到的事件标识
stPollFd.events = POLLIN;
stPollFd.revents = 0;
POLL_FD_VECTOR PollFdVector;
PollFdVector.push_back(stPollFd);
//侦听主循环
int s32ReadyNum = 0;
while (1)
{
s32ReadyNum = poll(&*PollFdVector.begin(), PollFdVector.size(), -1);
if (s32ReadyNum == -1)
{
if (errno == EINTR)
{
continue;
}
SHOW_ERR("\n");
}
else if (s32ReadyNum == 0) // timeout
{
continue;
}
s32Ret = AcceptConnect(PollFdVector);
if(SUCCESS == s32Ret)
{
s32ReadyNum -- ;
if(0 == s32ReadyNum)
{
continue;
}
}
ReadData(PollFdVector);
}
return 0;
}