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