您的位置:程序门 -> c/c++ -> c++ 语言



关于epoll引起accept返回错误的地址和端口的问题


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


关于epoll引起accept返回错误的地址和端口的问题
发表于:2008-01-21 01:05:41 楼主
小弟最近做epoll方面的研究,但是遇到了一个很郁闷的问题,最后检测到是accept返回的ip和port都不对(因为最后epoll_error返回了107的错误),但是估计可能是epoll写的有问题才导致了出现这种奇怪的现象。大家看看能不能解决

内核版本       2.6.9-5.el
操作系统     readhat   enterprise   4   (linux)

出现错误的方法     :
                    1.   启动server
                    2.   运行客户端一次
                    3.   再另一个窗口再运行客户端一次

内容过长!!   汗     代码一会贴上来
发表于:2008-01-21 01:07:121楼 得分:0
代码如下:
          服务器端:   注意修改一下ip和端口   在编译
c/c++ code
#include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <signal.h> #include <string.h> #include <pthread.h> #include <sys/epoll.h> #include <map> #include <iostream> const int max_file = 300; const char* protocol_header = "<?xml"; const char* protocol_end = "</db_server>"; const char* ip = "192.168.1.222"; const int port = 5555; char* protocoltwo = "<?xml version =\"1.0\" encoding =\"utf-8\"?><db_server><cmd>indexserverloadreq</cmd><start>0</start><range>100</range></db_server>"; char* responsetwo = "two"; void setsocknoblock(int sockfd) { int opts = 0; opts = fcntl(sockfd, f_getfl); if(opts < 0 ) { std::cout<< "fcntl(sock,setfl,opts) one failed" << std::endl; } opts = opts|o_nonblock; if(fcntl(sockfd, f_setfl,opts) < 0) { std::cout <<"fcntl(sock,setfl,opts) two failed" <<std::endl; } return ; } bool resetsockout(int sockfd, int epollfd) { struct epoll_event ev; memset(&ev, '\0', sizeof(ev)); ev.data.fd = sockfd; ev.events = epollout|epollerr|epollhup|epollet|epolloneshot; if (epoll_ctl(epollfd, epoll_ctl_mod, sockfd,&ev) < 0) { std::cout << "reset socket epollout failed" << std::endl; return false; } else { return true; } } bool resetsockin(int sockfd, int epollfd) { struct epoll_event ev; memset(&ev, '\0', sizeof(ev)); ev.data.fd = sockfd; ev.events = epollin|epollerr|epollhup|epollet|epolloneshot; if (epoll_ctl(epollfd, epoll_ctl_mod, sockfd,&ev) < 0) { std::cout <<"reset socket epollin failed" << std::endl; return false; } else { return true; } } bool delsockfrmepoll(int sockfd, int epollfd) { struct epoll_event ev; memset(&ev, '\0', sizeof(ev)); ev.data.fd = sockfd; if (epoll_ctl(epollfd, epoll_ctl_del, sockfd, &ev) < 0) { std::cout << "del sock from epoll is failed" << std::endl; return false; } shutdown(sockfd, shut_rdwr); close(sockfd); std::cout << "delsockfrmepoll " << sockfd << std::endl; return true; } bool readbuffer(int sockfd, char* buffer, int length) { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000* 3; whiletrue) { if(length <= 0) { return true; } int recvnum = 0; //recvnum = recv(sockfd, buffer, length, 0); recvnum = read(sockfd, buffer, length); if (recvnum < 0) { if (errno == eagain || errno == eintr) { std::cout << "continue " << std::endl; continue; } else { std::cout << "receive errno " << std::endl; return false; } } else if (recvnum == 0) { std::cout << "receive data not complete but client send fin " << std::endl; return false; } else if (recvnum > 0) { buffer += recvnum; length -= recvnum; } select(1, null, null, null, &tv); } return false; } bool sendbuffertoclient(int sockfd, char* buffer, int length) { struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 1000 * 3; whiletrue) { if(length <= 0) { return true; } int sendnum = 0; //sendnum = send(sockfd, buffer, length, 0); sendnum = write(sockfd, buffer, length); if (sendnum > 0) { buffer += sendnum; length -= sendnum; } else if (sendnum < 0) { if (errno == epipe) { std::cout << "send broken pipe" << std::endl; return false; } } else if (sendnum == 0) { std::cout << "send not complete but client fin" << std::endl; return false; } select(1, null, null, null, &tv); } return false; }
该帖子于2008-01-21 22:39:25被版主修改
发表于:2008-01-21 01:07:342楼 得分:0
c/c++ code
int main() { signal(sigpipe, sig_ign);//ignore signal, don't shutdown service struct epoll_event events[max_file], ev; memset(events, '\0', sizeof(events)); memset(&ev, '\0', sizeof(ev)); int epollfd = 0; epollfd = epoll_create(max_file); if (epollfd < 0) { std::cout << "epoll_create errno"<< errno << std::endl; } int sockfd = 0; sockfd = socket(af_inet, sock_stream, 0); setsocknoblock(sockfd); ev.data.fd = sockfd; ev.events = epollin|epollerr|epollhup|epollet; int epollerror = 0; epollerror = epoll_ctl(epollfd, epoll_ctl_add, sockfd, &ev); if (epollerror < 0) { std::cout << "epoll_ctl add sockfd errno " << errno<<std::endl; } int opt = so_reuseaddr; setsockopt(sockfd, sol_socket, so_reuseaddr, &opt, sizeof(opt)); struct sockaddr_in serviceaddr; memset(&serviceaddr, '\0', sizeof(serviceaddr)); serviceaddr.sin_family = af_inet; serviceaddr.sin_port = htons(port); if(inet_pton(af_inet,ip,&serviceaddr.sin_addr) <= 0) { std::cout <<"can not create a network address structure" << std::endl; close(sockfd); } if (bind(sockfd, (struct sockaddr*)&serviceaddr, sizeof(serviceaddr))<0) { std::cout<<"can not bind a socket"<<std::endl; close(sockfd); } if (listen(sockfd, 1024) < 0) { std::cout << "can not listen for connect" << std::endl; close(sockfd); } char recvbuffer[8193]; memset(recvbuffer, '\0', 8193); char sendbuffer[8193]; memset(sendbuffer, '\0', 8193); int i = 0; for( ; ; ) { int epollfds = 0; epollfds = epoll_wait(epollfd, events, max_file, -1); for(i = 0; i < epollfds; ++i ) { if (events.data.fd== sockfd) { struct sockaddr_in clientaddr; memset(&clientaddr, '\0', sizeof(clientaddr)); int clientsockfd = 0; socklen_t clientaddrlen = sizeof(clientaddr); clientsockfd = accept(sockfd, (struct sockaddr*)&clientaddr, &clientaddrlen); std::cout << "clientsockfd is : " << clientsockfd << std::endl; std::cout << "client address is : " << inet_ntoa(clientaddr.sin_addr) << std::endl; std::cout << "client port is : " << ntohs(clientaddr.sin_port)<< std::endl; if (clientsockfd < 0) { std::cout << "accept error " << errno<<std::endl; exit(1); } else { setsocknoblock(clientsockfd); ev.data.fd = clientsockfd; ev.events = epollin|epollerr|epollhup|epollet|epolloneshot; int epollerror = 0; epollerror = epoll_ctl(epollfd, epoll_ctl_add, clientsockfd, &ev); if (epollerror < 0) { std::cout << "epoll_ctl add clientsockfd errno " << errno<<std::endl; } } } else { if (events.events & epollerr) { std:: cout << "epollerr "<< std::endl; std:: cout << "errno "<< errno <<"fd is : " << events.data.fd<<std::endl; delsockfrmepoll(events.data.fd, epollfd); } else if (events.events & epollhup) { std:: cout << "epollhup "<< std::endl; delsockfrmepoll(events.data.fd, epollfd); } else if (events.events & epollin) { bool iostatus = false; iostatus = readbuffer(events.data.fd, recvbuffer, 126); //126是xml的长度 if (iostatus) { /* std::cout << "fd is : " <<events.data.fd << std::endl; std::cout << "recvbuffer is : " <<recvbuffer << std::endl; */ resetsockout(events.data.fd, epollfd); } else { delsockfrmepoll(events.data.fd, epollfd); } } else if (events.events & epollout) { if (strncmp(recvbuffer, protocoltwo, strlen(recvbuffer)) == 0) { strncpy(sendbuffer, responsetwo, strlen(responsetwo)); bool iostatus = false; iostatus = sendbuffertoclient(events.data.fd, sendbuffer, strlen(sendbuffer)); if (iostatus) { /* std::cout << "fd is : " <<events.data.fd << std::endl; std::cout << "sendbuffer is : " <<sendbuffer << std::endl; */ resetsockin(events.data.fd, epollfd); } else { delsockfrmepoll(events.data.fd, epollfd); } } } } } } return 0; }
该帖子于2008-01-21 22:40:36被版主修改
发表于:2008-01-21 01:07:593楼 得分:0
客户端代码:注意修改ip和端口指向服务器,编译的时候用-lpthread(因为模拟多个用户)

c/c++ code
#include<iostream> #include<string.h> #include<sys/socket.h> #include<sys/types.h> #include<netdb.h> #include <stdio.h> #include <time.h> #include <unistd.h> #include <errno.h> #include <pthread.h> #include <errno.h> using namespace std; #define thread_number 10 char *buf = "<?xml version =\"1.0\" encoding =\"utf-8\"?><db_server><cmd>indexserverloadreq</cmd><start>0</start><range>100</range></db_server>"; void* process(void* arg); int main(int argc, char** argv) { pthread_t* threadids= null; threadids = new(nothrow) pthread_t[thread_number]; if (threadids == null) { exit(1); } forint i = 0; i < thread_number; i++) { if (pthread_create(&threadids, null, process, null) != 0) { cout <<"create thread errno is " << errno <<" errno end"<< endl; cout << eagain <<endl; exit(1); } } cout <<"pthread join begin"<< endl; forint j = 0; j < thread_number; j++) { if (pthread_join(threadids[j], null) != 0) { cout <<"join thread errno is " << errno <<" errno end"<< endl; exit(1); } } cout <<"pthread join end"<< endl; delete [] threadids; threadids = null; return 0; } void* process(void* arg) { struct hostent *he; whiletrue) { if (null == (he = gethostbyname( "192.168.1.222" ))) { continue; } else { break; } } int fd; if-1 == (fd = socket(af_inet, sock_stream, 0))) { cout <<"socket create error : " << errno << endl; exit(1); } struct sockaddr_in server; memset(&server, '\0', sizeof(server)); server.sin_family = af_inet; server.sin_port = htons(5555); server.sin_addr = *((in_addr* )he->h_addr); if-1 == connect(fd, (struct sockaddr* )&server, sizeofstruct sockaddr))) { cout <<"connect : " << errno << endl; exit(1); } //int i = 0; whiletrue) //for(i = 0; i < 500; i++) { cout << "send begin" << endl; int sendnum = 0; sendnum = send(fd, buf, strlen(buf), 0); cout << "fd " << fd << endl; if (sendnum <= 0) { cout << "send errno " <<errno<< endl; cout << "sendnumber is : " << sendnum << " fd is " << fd <<endl; } cout << "send end" << endl; cout << "recv begin" << endl; char resbuf[1024*8+1]; memset(resbuf, '\0', sizeof(resbuf)); int recvnumber = 0; if ((recvnumber=recv(fd, resbuf, 3, 0)) <= 0) { cout << "recv errno " <<errno<< endl; cout << "recvnumber is : " << recvnumber << " fd is " << fd <<endl; } else { cout << resbuf << endl; } cout << "recv end" << endl; } shutdown(fd, shut_rdwr); close(fd); return null; }
该帖子于2008-01-21 22:41:14被版主修改
发表于:2008-01-21 01:17:004楼 得分:0
小弟最近做epoll方面的研究,但是遇到了一个很郁闷的问题,最后检测到是accept返回的ip和port都不对(因为最后epoll_error返回了107的错误),但是估计可能是epoll写的有问题才导致了出现这种奇怪的现象。
==========
研究,恩,看来兄弟挺厉害的,都研究了!但是从贴代码的方式来看,兄弟只有在有问题的时候才会在csdn上说话啊!
发表于:2008-01-21 01:42:335楼 得分:0
恩     如果自己能解决就不好麻烦别人了
发表于:2008-01-21 10:49:116楼 得分:0
zlmnjy  
小亮  
等   级:
  发表于:2008-01-21   01:42:335楼   得分:0  
恩           如果自己能解决就不好麻烦别人了  
===============
唉,没明白我的意思,就是说,你没想过帮助别人,只想过寻求别人的帮助。这点从你贴代码的方式就看出来了——没有代码格式。
发表于:2008-01-21 13:15:077楼 得分:0
o     这样       不好意思!!   不是很懂怎么做!   对了还有一个什么送分也不是很明白   不好意思了!!


快速检索

最新资讯
热门点击