Do you ever call listen() on the server socket?

 - Alex

On Mon, Jun 20, 2011 at 10:08 AM, Cong <[email protected]> wrote:

> 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
>
_______________________________________________
libev mailing list
[email protected]
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev

Reply via email to