免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1515 | 回复: 1
打印 上一主题 下一主题

请教 EPOLL 使用问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-12-16 21:30 |只看该作者 |倒序浏览
使用EPOLL , 的TCP服务器
生成俩个epoll fd , 一个用于接收,一个用于发送 ,这样做是否正确

我使用下面的模型时发生过两种异常情况:
1。因为我的Send函数是给其他消息处理线程调用的,会发生处理线程挂住的情况,但是过一段时间(1,2小时,没具体看)又恢复了,经过跟踪,应该是挂在 Send函数这里
2. 程序运行了几天后,很多新连接上来,接受处理完第一个包后,调用Send返回时,socket 就收到 input/output error 的错误,然后关闭了socket。但是有少部分连接可以成功


  1. epSendfd = epoll_create(1);
  2. epRecvfd = epoll_create(MAX_SOCKET_NUM);

  3. 每有一个新连接上来
  4. struct epoll_event ev;
  5. ev.data.fd=fd;
  6. ev.events=EPOLLIN|EPOLLET;
  7. epoll_ctl(epRecvfd,EPOLL_CTL_ADD,fd,&ev);

  8. 接收是一个接收线程完成,做的事情就是
  9. while(IsExit() == false)
  10. {

  11. int nfds=epoll_wait(epRecvfd,events,MAX_SOCKET_NUM,400);
  12. ....
  13. }

  14. 发送只是提供一个函数,给其他处理线程调用
  15. int CTTcpBase::Send(unsigned int id, const char* buffer, int length)
  16. {
  17. 。。。
  18. struct epoll_event ev,events[1];
  19. ev.data.fd=fd;
  20. ev.events=EPOLLOUT|EPOLLET;
  21. epoll_ctl(epSendfd,EPOLL_CTL_ADD,fd,&ev);

  22. int nfds=epoll_wait(epSendfd,events,1,400);
  23. ...
  24. ret = ::send(fd, buffer + write, length - write, 0);
  25. ...
  26. epoll_ctl(epSendfd,EPOLL_CTL_DEL,fd,&ev);
  27. }

复制代码


我想问问,当对于一个连接fd,同时发生
epoll_wait(epRecvfd,events,MAX_SOCKET_NUM,400);

epoll_wait(epSendfd,events,1,400);
会不会有问题

[ 本帖最后由 qinyd 于 2006-12-16 22:02 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2006-12-16 21:38 |只看该作者
顺便问问 我的 send函数 这样写有没有问题

  1. int CTTcpBase::Send(unsigned int id, const char* buffer, int length)
  2. {
  3.         SOCKET fd = m_pSocketSet->GetSocketID(id);
  4.         if(fd == INVALID_SOCKET)
  5.                 return -1;
  6.        
  7.         int ret = 0;
  8.         int write = 0;
  9.         //struct pollfd rset[1];
  10.         struct epoll_event ev,events[1];

  11.                
  12.         ev.data.fd=fd;
  13.         ev.events=EPOLLOUT|EPOLLET;
  14.         epoll_ctl(epSendfd,EPOLL_CTL_ADD,fd,&ev);

  15.         while(write < length)
  16.         {
  17.                
  18.                 int nfds=epoll_wait(epSendfd,events,1,400);  
  19.                 if(nfds < 0)
  20.                 {
  21.                         if(m_pLog)
  22.                         {
  23.                                 m_pLog->print("[TCP %d] WARN! select socket error while sending packet\n",
  24.                                                           id);
  25.                         }
  26.                         DelListen(epRecvfd,fd);
  27.                         m_pSocketSet->DeleteSocket(id);
  28.                         return -1;               
  29.                 }

  30.                 ret = ::send(fd, buffer + write, length - write, 0);
  31.                 if(ret == SOCKET_ERROR || ret == 0)
  32.                 {
  33.                         if(m_pLog)
  34.                                 m_pLog->print("[TCP %d] WARN! send packet error!\n", id);
  35.                         DelListen(epRecvfd,fd);
  36.                         m_pSocketSet->DeleteSocket(id);
  37.                         return -1;
  38.                 }

  39.                 write += ret;
  40.         }
  41.         epoll_ctl(epSendfd,EPOLL_CTL_DEL,fd,&ev);

  42.         return 0;
  43. }
复制代码

[ 本帖最后由 qinyd 于 2006-12-16 21:58 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP