书到用时方恨少,一切尽在不言中
#include <iostream>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h> using namespace std; #define MAXLINE 5
#define OPEN_MAX 100
#define LISTENQ 20
#define SERV_PORT 5000
#define INFTIM 1000 void setnonblocking(int sock)
{
int opts;
opts=fcntl(sock,F_GETFL);
if(opts<)
{
perror("fcntl(sock,GETFL)");
return;
}
opts = opts|O_NONBLOCK; if(fcntl(sock,F_SETFL,opts)<)
{
perror("fcntl(sock,SETFL,opts)");
return;
}
} void CloseAndDisable(int sockid, epoll_event ee)
{
close(sockid);
ee.data.fd = -;
} ssize_t socket_send(int sockfd, const char* buffer, size_t buflen)
{
ssize_t tmp;
size_t total = buflen;
const char *p = buffer; while()
{
tmp = send(sockfd, p, total, );
if(tmp < )
{
if(errno == EINTR)
return -; if(errno == EAGAIN)
{
usleep();
continue;
}
return -;
} if((size_t)tmp == total)
return buflen;
total -= tmp;
p += tmp;
}
return tmp;
}
int main()
{
int i, maxi, listenfd, connfd, sockfd,epfd,nfds, portnumber;
char line[MAXLINE*];
socklen_t clilen;
portnumber = ; struct epoll_event ev,events[];
epfd=epoll_create(); struct sockaddr_in clientaddr;
struct sockaddr_in serveraddr;
listenfd = socket(AF_INET, SOCK_STREAM, ); memset(&serveraddr, , sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
serveraddr.sin_port=htons(portnumber); bind(listenfd,(sockaddr *)&serveraddr, sizeof(serveraddr));
listen(listenfd, LISTENQ); ev.data.fd=listenfd;
ev.events=EPOLLIN|EPOLLET; epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev); maxi = ; int bOut = ;
for ( ; ; )
{
if (bOut == )
break;
nfds=epoll_wait(epfd,events,,-);
//printf("wait %d returns\n",nfds);
for(i=;i<nfds;++i)
{
if(events[i].data.fd==listenfd)//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口
{
connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen);
if(connfd<){
perror("connfd<0");
return ();
} char *str = inet_ntoa(clientaddr.sin_addr);
cout << "accapt a connection from " << str << endl;
setnonblocking(connfd);
ev.data.fd=connfd;
ev.events=EPOLLIN | EPOLLET;
//注册ev
epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
}
else if(events[i].events & EPOLLIN)
{
cout << "EPOLLIN" << endl;
if ( (sockfd = events[i].data.fd) < )
continue; cout << "START READ" << endl;
char * head = line;
int recvNum = ;
int count = ;
bool bReadOk = false;
while()
{
recvNum = recv(sockfd, head+count, MAXLINE-, );
if(recvNum < )
{
if(errno == EAGAIN)
{//已没数据 不阻塞等待
bReadOk = true;
break;
}
else if (errno == ECONNRESET)
{
CloseAndDisable(sockfd, events[i]);
cout << "counterpart send out RST\n";
break;
}
else if (errno == EINTR)
{//有数据但未读到断了,所以要接着读
continue;
}
else
{
CloseAndDisable(sockfd, events[i]);
cout << "unrecovable error\n";
break;
}
}
else if( recvNum == )
{
CloseAndDisable(sockfd, events[i]);
cout << "counterpart has shut off\n";
break;
} count += recvNum;
if ( recvNum == MAXLINE-)
{
cout << "sleeping..."<<endl;
sleep();
cout << "recvNum == MAXLINE-1\n"<<endl;
continue;
}
else // 0 < recvNum < MAXLINE-1
{
cout << "0 < recvNum < MAXLINE-1"<<endl;
bReadOk = true;
break; // 退出while(1),表示已经全部读完数据
} } if (bReadOk == true)
{
line[count] = '\0';
cout << "we have read from the client : " << line;
ev.data.fd=sockfd;
ev.events = EPOLLOUT | EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
}
else if(events[i].events & EPOLLOUT) // 如果有数据发送
{
cout << "EPOLLOUT" << endl;
const char str[] = "";
//printf("%d\n",sizeof(str));
memcpy(line, str, sizeof(str));
//cout << line << endl;
printf("d %d u %u lu %lu\n",i,i,i);
sockfd = events[i].data.fd;
int bWritten = ;
int writenLen = ;
int count = ;
char * head = line;
bWritten=socket_send(sockfd,head,strlen(head));
if (bWritten == strlen(head))
{
ev.data.fd=sockfd;
ev.events=EPOLLIN | EPOLLET;
epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
}
}
}
}
return ;
}

关于epoll和accept的注意点,参见http://www.ccvita.com/515.html

最新文章

  1. SQL用法操作合集
  2. 《大道至简》第一章读后感--JAVA语言伪代码形式
  3. 网易云课堂JS笔记
  4. 【python】pymongo查找某一时间段的数据
  5. 插件~使用ECharts动态在地图上标识点
  6. 《计算机问题求解》总结——2014年CCF计算机课程改革导教班(2014.07.11)
  7. HDU-1896 Stones
  8. web负载均衡整理
  9. HDU2673:shǎ崽 OrOrOrOrz
  10. Leetcode-颠倒整数
  11. 盘点 Python 中的那些冷知识(一)
  12. html_Dom
  13. MySQL之视图、触发器、事务、存储过程、函数
  14. MongDB 数据结构
  15. [Linux] Nginx响应压缩gzip
  16. zabbix3.4.6之自动发现与自动注册
  17. Inside The C++ Object Model(四)
  18. AltiumDesigner PCB中栅格与格点的切换
  19. python自动化之PDF
  20. Java 8 : Stream API 练习

热门文章

  1. 微博公众平台(二)-- Token验证代码
  2. 利用python将二值csv格式转换为矩阵
  3. 正则获取HTML代码中img的src地址
  4. 为什么 &quot;auto a = 1;&quot; 在C语言中可以编译通过?
  5. 并查集(union-find)算法
  6. GitHub 上 57 款最流行的开源深度学习项目
  7. spoj 371 Boxes
  8. Git for Windows - The Program can&#39;t start because libiconv2.dll is missing
  9. win8.1系统的安装方法详细图解教程
  10. Dom4j把xml转换成Map(非固定格式)