Skip site navigation (1)Skip section navigation (2)
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>