Date: Sat, 3 Jan 2015 18:37:34 +0300 From: =?iso-8859-1?B?VmljdG9yIEZyYW7nYQ==?= <victorfranlopes@outlook.com> To: "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org> Subject: kqueue nonblocking socket timeout with siege Message-ID: <COL127-W1755795B8BA5646BB11280B75A0@phx.gbl>
next in thread | raw e-mail | index | archive | help
I'm trying to create a server that works with multiple connections using kq= ueue. After much research=2C I developed my code to test the technology.=20 So I started testing with the siege=2C however=2C after an average of 300 r= equests=2C the server begins to become unstable=2C sometimes the siege poin= ts timeout=2C sometimes it can get the answer. =0A= I 'm using the g ++ to compile. =0A= Here is my code. #include <iostream>=0A= #include <netinet/in.h>=0A= #include <netinet/tcp.h>=0A= #include <sys/socket.h>=0A= #include <cstring>=0A= #include <cerrno>=0A= #include <cstdlib>=0A= #include <unistd.h>=0A= #include <sys/time.h>=0A= #include <sys/types.h>=0A= #include <sys/event.h>=0A= #include <sstream>=0A= =0A= using namespace std=3B=0A= =0A= struct client_s {=0A= int fd=3B=0A= int type=3B=0A= socklen_t addrlen=3B=0A= struct sockaddr addr=3B=0A= int bufflen=3B=0A= }=3B=0A= =0A= int main (int argc=2C char *argv[]) {=0A= =0A= int portN=2C sockFD=2C sockOPT=2C eveCT=2C optRET=2C bindRET=2C listenR= ET=2C kernelQUE=2C nev=2C connectionFlags=2C numBT=3B=0A= struct sockaddr_in sockADDR=3B=0A= struct kevent events[2]=3B=0A= struct kevent changes[2]=3B=0A= =0A= if (argc < 2) {=0A= cerr << "Argument required: [port]" << endl=3B =0A= return -1=3B=0A= }=0A= =0A= portN =3D atoi(argv[1])=3B=0A= =0A= sockFD =3D socket(AF_INET=2C SOCK_STREAM | SOCK_NONBLOCK=2C IPPROTO_TCP= )=3B=0A= =0A= if (sockFD < 0) {=0A= cerr << "Error while opening socket: " << strerror(errno) << endl= =3B=0A= return -1=3B=0A= } else=0A= clog << "Socket openend. Nonblock socket defined." << endl=3B=0A= =0A= sockOPT =3D 1=3B=0A= =0A= optRET =3D setsockopt(sockFD=2C SOL_SOCKET=2C SO_REUSEADDR=2C &sockOPT= =2C sizeof(sockOPT))=3B // Avoid TIME_WAIT=0A= if (optRET < 0) {=0A= cerr << "Error while setting flag SO_REUSEADDR: " << strerror(errno= ) << endl=3B=0A= return -1=3B=0A= } else=0A= clog << "SO_REUSEADDR flag ok." << endl=3B=0A= =0A= optRET =3D setsockopt(sockFD=2C IPPROTO_TCP=2C TCP_NODELAY=2C &sockOPT= =2C sizeof(sockOPT))=3B // Avoid socket buffer=0A= if (optRET < 0) {=0A= cerr << "Error while setting flag TCP_NODELAY: " << strerror(errno)= << endl=3B=0A= return -1=3B=0A= } else=0A= clog << "TCP_NODELAY flag ok." << endl=3B=0A= =0A= memset(&sockADDR=2C 0=2C sizeof(struct sockaddr_in))=3B=0A= =0A= sockADDR.sin_family =3D AF_INET=3B=0A= sockADDR.sin_port =3D htons(portN)=3B=0A= sockADDR.sin_addr.s_addr =3D INADDR_ANY=3B=0A= =0A= bindRET =3D bind(sockFD=2C (struct sockaddr*)&sockADDR=2C sizeof(sockAD= DR))=3B=0A= =0A= if (bindRET < 0) {=0A= cerr << "Error while binding socket: " << strerror(errno) << endl= =3B=0A= return -1=3B=0A= } else=0A= clog << "Socket binded." << endl=3B=0A= =0A= listenRET =3D listen(sockFD=2C 1000)=3B=0A= =0A= if (listenRET < 0) {=0A= cerr << "Error while start listening the port: " << strerror(errno)= << endl=3B=0A= return -1=3B=0A= } else=0A= clog << "Socket is listening the port " << argv[1] << endl=3B=0A= =0A= kernelQUE =3D kqueue()=3B=0A= =0A= if (kernelQUE < 0) {=0A= cerr << "Error on creating kqueue." << endl=3B=0A= return -1=3B=0A= } else=0A= clog << "Starting kernel queue." << endl=3B=0A= =0A= memset(events=2C 0=2C sizeof(events))=3B=0A= memset(changes=2C 0=2C sizeof(changes))=3B=0A= =0A= EV_SET(&changes[0]=2C sockFD=2C EVFILT_READ=2C EV_ADD | EV_ENABLE=2C 0= =2C 0=2C 0)=3B=0A= =0A= eveCT =3D 1=3B=0A= for (=3B=3B) {=0A= =0A= nev =3D kevent(kernelQUE=2C changes=2C eveCT=2C events=2C eveCT=2C = NULL)=3B=0A= =0A= if (nev < 0) {=0A= cerr << "Error resolving event." << endl=3B=0A= return -1=3B=0A= }=0A= =0A= for (int i =3D 0=3Bi <=3D nev=3B i++) {=0A= struct client_s * client =3D static_cast<client_s *>(malloc(siz= eof(struct client_s)))=3B=0A= =0A= if (events[i].ident =3D=3D sockFD && events[i].filter =3D=3D EV= FILT_READ) {=0A= client->fd =3D accept4(sockFD=2C &client->addr=2C &client->= addrlen=2C SOCK_NONBLOCK)=3B=0A= =0A= if (client->fd < 0) {=0A= cerr << "Error while accepting new connection." << stre= rror(errno) << endl=3B=0A= free(client)=3B=0A= } else {=0A= client->type =3D 2=3B=0A= client->bufflen =3D 0=3B =0A= EV_SET(&changes[1]=2C client->fd=2C EVFILT_READ=2C EV_A= DD | EV_ENABLE=2C 0=2C 0=2C client)=3B=0A= eveCT=3D2=3B=0A= }=0A= }=0A= =0A= if (events[i].filter =3D=3D EVFILT_READ && events[i].udata && e= vents[i].data > 0) {=0A= client =3D static_cast<client_s *>(events[i].udata)=3B=0A= if (client->type =3D=3D 2) {=0A= =0A= client->type++=3B=0A= char *buffer =3D new char[events[i].data]=3B=0A= client->bufflen =3D events[i].data=3B=0A= numBT =3D recv(client->fd=2C buffer=2C events[i].data= =2C 0)=3B=0A= delete[] buffer=3B=0A= if (numBT =3D=3D events[i].data) {=0A= EV_SET(&changes[1]=2C client->fd=2C EVFILT_READ=2C = EV_DISABLE=2C 0=2C 0=2C 0)=3B=0A= kevent(kernelQUE=2C &changes[1]=2C 1=2C NULL=2C 0= =2C 0)=3B =0A= EV_SET(&changes[1]=2C client->fd=2C EVFILT_WRITE=2C= EV_ADD | EV_ENABLE=2C 0=2C 0=2C client)=3B=0A= } else=0A= cerr << "Error while reading." << strerror(errno) <= < endl=3B=0A= }=0A= } else if (events[i].filter =3D=3D EVFILT_WRITE && events[i].ud= ata) {=0A= client =3D static_cast<client_s *>(events[i].udata)=3B=0A= if (client->type =3D=3D 3) { =0A= string query("HTTP/1.1 200 OK\r\n\r\nKernel events=2C b= aby!"=3B)=3B=0A= numBT =3D send(client->fd=2C query.c_str()=2C query.siz= e()=2C 0)=3B=0A= if (numBT =3D=3D query.size()) {=0A= EV_SET(&changes[1]=2C client->fd=2C EVFILT_WRITE=2C= EV_DISABLE=2C 0=2C 0=2C 0)=3B=0A= kevent(kernelQUE=2C &changes[1]=2C 1=2C NULL=2C 0= =2C 0)=3B=0A= memset(&changes[1]=2C 0=2C sizeof(struct kevent))= =3B=0A= shutdown(client->fd=2C SHUT_RDWR)=3B=0A= close(client->fd)=3B=0A= free(client)=3B=0A= eveCT=3D1=3B=0A= } else=0A= cerr << "Error while writing." << strerror(errno) <= < endl=3B=0A= }=0A= }=0A= }=0A= }=0A= =0A= shutdown(sockFD=2C SHUT_RDWR)=3B=0A= close(sockFD)=3B=0A= =0A= return 0=3B=0A= } =
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?COL127-W1755795B8BA5646BB11280B75A0>