连接EPOLL服务器时出现错误:( Connection reset by peer)

oneonenight 2011-07-08 09:56:15
当连接数到达几百时出现上述错误。大家有没有一个比较稳定的EPOLL TCP服务器模型?下面是我的代码:

int epoll::setnonblocking(int sock)
{
long arg;

if (fcntl (sock, F_GETFL, &arg) == -1)
{
return 1;
}
arg = arg | O_NONBLOCK;
if (fcntl (sock, F_SETFL, arg) == -1)
{
return 2;
}
return 0;
}

bool epoll::StartServer(const char* ip,int port,int timeout)
{
m_timeout=timeout;
struct epoll_event ev;
ssize_t n;
int ret=0;
int optval=1;
m_epfd = epoll_create(10000);
struct sockaddr_in serveraddr;
m_listenfd = socket(AF_INET,SOCK_STREAM,0);

if(setsockopt(m_listenfd,SOL_SOCKET,SO_REUSEADDR,&optval, sizeof(optval)) == -1)
{
printf("setsockopt error\n");
exit(1);
}

struct linger ln;
ln.l_onoff = 1;
ln.l_linger = 0;
if(setsockopt(m_listenfd, SOL_SOCKET, SO_LINGER, (void *) &ln,sizeof (struct linger)) < 0)
{
printf("setlinger error\n");
exit(1);
}

setnonblocking(m_listenfd);
ev.data.fd = m_listenfd;
ev.events = EPOLLIN | EPOLLHUP | EPOLLERR;
epoll_ctl(m_epfd,EPOLL_CTL_ADD,m_listenfd,&ev);
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family = AF_INET;

inet_aton(ip,&(serveraddr.sin_addr));
serveraddr.sin_port = htons(port);
bind(m_listenfd,(struct sockaddr *)&serveraddr,sizeof(serveraddr));
listen(m_listenfd, 10);
int on = 1;
setsockopt(m_listenfd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));

pthread_t tid;
for (int loops = 0; loops < MAX_THREAD_NUM; loops++)
{
ret=pthread_create(&tid,NULL, RecvMsg,this);
if (ret!=0)
{
printf("create thread error\n");
exit(1);
}
}

ret+=pthread_create(&tid,NULL, EpollFunc,this);



}

void* epoll::EpollFun(void* arg)
{
int i,connfd,nfds;

epoll* cs=(epoll*)arg;

struct epoll_event ev,events[10000];
while(true)
{
nfds = epoll_wait(cs->m_epfd,events,10000,-1);
for(i = 0; i < nfds ; ++i)
{
if(events[i].data.fd == cs->m_listenfd)
{
socklen_t clilen= sizeof(struct sockaddr);
struct sockaddr_in clientaddr;
int sign = 1;
while((connfd = accept(cs->m_listenfd,(struct sockaddr *)&clientaddr,&clilen)) < 0)
{
if(errno == EINTR)
continue;
if(errno != EAGAIN && errno != EWOULDBLOCK)
{
sign = 0;
break;
}
}
if(sign == 1)
{

struct linger ln;
ln.l_onoff = 1;
ln.l_linger = 0;
setsockopt(connfd, SOL_SOCKET, SO_LINGER, (void *) &ln,sizeof (struct linger));
struct timeval timeout = {10,0};
setsockopt(connfd,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(struct timeval));
cs->setnonblocking(connfd);

struct epoll_event ev;
char *str = inet_ntoa(clientaddr.sin_addr);
ev.data.u64 = 0UL;
ev.data.fd = connfd;
ev.events = EPOLLIN | EPOLLONESHOT | EPOLLHUP | EPOLLERR ;
epoll_ctl(cs->m_epfd,EPOLL_CTL_ADD,connfd,&ev);
}
}
else if(events[i].events & EPOLLHUP)
{
close(events[i].data.fd);
cs->DelConn(events[i].data.fd);


} else if(events[i].events & EPOLLERR)
{
epoll_ctl(cs->m_epfd,EPOLL_CTL_DEL,events[i].data.fd,&ev);

}
else if(events[i].events & EPOLLIN)
{
pthread_mutex_lock(&cs->m_ClientAcceptMutex);
cs->m_ClientList.push_back(events[i].data.fd);
pthread_cond_signal(&cs->m_cond);
pthread_mutex_unlock(&cs->m_ClientAcceptMutex);
}
else
{
close(events[i].data.fd);
}

}
}


return 0;

}
...全文
412 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzj102816 2011-08-08
  • 打赏
  • 举报
回复
一般700以上的链接就出现这样的问题。
我搭建的环境是客户端在虚拟机,服务器在宿主机,接入局域网,客户端进行1k左右的链接并发。然后出现这样的错误。
据说可以重连解决,但重连可能违背了服务器测试并发量的初衷。
zzj102816 2011-08-08
  • 打赏
  • 举报
回复
遭遇同样的问题,等待大神答复
oneonenight 2011-07-08
  • 打赏
  • 举报
回复
当客户端与服务器同一机器时,连接数上万都没有问题,不同机器才有上述问题,不知道什么原因
justkk 2011-07-08
  • 打赏
  • 举报
回复

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧