书到用时方恨少,一切尽在不言中
#include#include #include #include #include #include #include #include #include #include using namespace std;#define MAXLINE 5#define OPEN_MAX 100#define LISTENQ 20#define SERV_PORT 5000#define INFTIM 1000void setnonblocking(int sock){ int opts; opts=fcntl(sock,F_GETFL); if(opts<0) { perror("fcntl(sock,GETFL)"); return; } opts = opts|O_NONBLOCK; if(fcntl(sock,F_SETFL,opts)<0) { perror("fcntl(sock,SETFL,opts)"); return; }}void CloseAndDisable(int sockid, epoll_event ee){ close(sockid); ee.data.fd = -1;}ssize_t socket_send(int sockfd, const char* buffer, size_t buflen){ ssize_t tmp; size_t total = buflen; const char *p = buffer; while(1) { tmp = send(sockfd, p, total, 0); if(tmp < 0) { if(errno == EINTR) return -1; if(errno == EAGAIN) { usleep(1000); continue; } return -1; } 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*50]; socklen_t clilen; portnumber = 5000; struct epoll_event ev,events[20]; epfd=epoll_create(256); struct sockaddr_in clientaddr; struct sockaddr_in serveraddr; listenfd = socket(AF_INET, SOCK_STREAM, 0); memset(&serveraddr, 0, 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 = 0; int bOut = 0; for ( ; ; ) { if (bOut == 1) break; nfds=epoll_wait(epfd,events,20,-1); //printf("wait %d returns\n",nfds); for(i=0;i < 0) continue; cout << "START READ" << endl; char * head = line; int recvNum = 0; int count = 0; bool bReadOk = false; while(1) { recvNum = recv(sockfd, head+count, MAXLINE-1, 0); if(recvNum < 0) { 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 == 0) { CloseAndDisable(sockfd, events[i]); cout << "counterpart has shut off\n"; break; } count += recvNum; if ( recvNum == MAXLINE-1) { cout << "sleeping..."<
关于epoll和accept的注意点,参见http://www.ccvita.com/515.html