Thanks Pierre-Yves!

I modified my code setting non-blocking socket using the way you described.
The problem is still the same. The function "setupServerSocket" has been
used before and seems working, still I pasted related functions as below:

int setupSocket(int theType)
{
    int fd = 0;
    if ((fd = socket(PF_INET, theType, 0)) == -1)
    {
        perror("setupSocket:socket");
        return -1;
    }

    int yes = 1;
    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
        perror("setsockopt");
        close(fd);
        return -1;
    }
    return fd;
}


void setServerSockAddr(sockaddr_in& theSockAddr, string theServerIp, ui16
theServerPort)
{
    theSockAddr.sin_family = AF_INET;
    theSockAddr.sin_port = htons(theServerPort);
    theSockAddr.sin_addr.s_addr = inet_addr(theServerIp.c_str());
    memset(theSockAddr.sin_zero, '\0', sizeof theSockAddr.sin_zero);
}

int setupServerSocket(int theType, string theServerIp, ui16 theServerPort)
{
    int fd = setupSocket(theType);
    if (fd < 0) {
        exit(1);
    }

    sockaddr_in serverAddr;
    setServerSockAddr(serverAddr, theServerIp, theServerPort);
    if (bind(fd, (sockaddr *)&serverAddr, sizeof serverAddr) == -1)
    {
        perror("setupServerSocket:bind");
        exit(1);
    }
    return fd;
}

And now I call the function setNonblocking at the previous line calling
fcntl.
int setNonblocking(int fd)
{
    int flags;
#if defined(O_NONBLOCK)
    if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
        flags = 0;
    }
    return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
#else
    flags = 1;
    return ioctl(fd, FIONBIO, &flags);
#endif
}



On Fri, Jun 17, 2011 at 5:20 PM, Pierre-Yves Kerembellec <
[email protected]> wrote:

> Hi Cong,
>
> > I'm a newbie to libev. I wrote a TCP server with libev. My program has a
> relatively simple structure, with accept_cb, read_cb, write_cb and
> timeout_cb defined. However, when I started it, I found the accept call back
> is called right away and being called about 60K+ times per second. Each
> "accept()" call sets the errno to EINVAL, since there's no connection. The
> program uses more than 50% CPU time.
>
> Do you properly bind the listening socket in the setupServerSocket ?
> Could you reproduce the content of the setServerSocket() function ?
>
> Also, instead of:
>
> fcntl(svrSockFd, F_SETFL, O_NONBLOCK);
>
> you should use:
>
> fcntl(svrSockFd, F_SETFL, fcntl(svrSockFd, F_GETFL, 0) | O_NONBLOCK);
>
> or even better (one less system call):
>
> int flag = 1;
> ioctl(svrSockFd, FIONBIO, &flag);
>
> > My question is that if this is correct? Or there could be something wrong
> with my program? If this is expected, then do I need to let the accept_cb to
> sleep to avoid making the CPU too busy? But wouldn't sleeping affect the
> performance of the server?
> >
> > Thanks for your attention!
> >
> > Shawn
> >
> > Part of my source code:
> > In main(),
> > ===============
> >
> >       int svrSockFd = setupServerSocket(SOCK_STREAM, g->m_ip, g->m_port);
> >
> >       // Make socket non-blocking.
> >       fcntl(svrSockFd, F_SETFL, O_NONBLOCK);
> >
> >       ev_io* acceptWatcher = (ev_io*)malloc(sizeof(ev_io));
> >
> >       // Init watcher
> >       ev_io_init(acceptWatcher, accept_cb, svrSockFd, EV_READ);
> >
> >       // Start watcher
> >       struct ev_loop* loop = EV_DEFAULT;
> >       ev_io_start(loop, acceptWatcher);
> >
> >       // Wait for events to arrive
> >       ev_run(loop, 0);
> >
> > The accept_cb:
> > =====================
> > static void accept_cb(struct ev_loop* loop, ev_io* w, int revents)
> > {
> >       Log::debug("serverSocket received data");
> >       int svrSockFd = w->fd;
> >
> >       // accept
> >       sockaddr_in clientAddress;
> >       socklen_t sin_size = (socklen_t)sizeof(clientAddress);
> >       int newSockFd = accept(svrSockFd, (sockaddr *)&clientAddress,
> &sin_size);
> >       if (newSockFd < 0) {    // -1, EAGAIN??
> >               if (errno == EINVAL) {
> >                       //cout << "no connection" << endl;
> >               } else {
> >                       perror("accept");
> >               }
> >       } else {
> >               // Handle the connection
> >                 ...
> >       }
> > }
>
>
> Regards,
> Pierre-Yves
>
>
_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Reply via email to