0

So i'm trying to create a minimal tcp server using kqueue, assuming all the previous details of socket(), bind(), listen() is working correctly given that i've tested them using a thread-per-connection model. why it hangs unexpectedly ?

struct kevent events;
struct kevent change_list;
// create a kqueue
int kq = kqueue();
if (kq < 0) {
    throw KqueueException();
}

// initialize the events we want to monitor
EV_SET(&events, sock, EVFILT_READ, EV_ADD, 0, 0, NULL);
// monitor the events
if (kevent(kq, &events, 1, NULL, 0, NULL) < 0) {
    throw KqueueException();
}

int nev;
while (true) {
    // wait for events to happen
    nev = kevent(kq, NULL, 0, &change_list, 1, NULL);
    if (nev < 0) {
        throw KqueueException();
    }
    else if (nev > 0) {
        // if the event fd is the same as the socket fd we have a new connection
        if ((int)change_list.ident == sock) {
            std::cout << "new connection" << std::endl;
            // accept the connection 
            int client_fd = accept(sock, NULL, NULL);
            if (client_fd < 0) {
                throw AcceptException();
            }
            // add the new connection to the events we want to monitor
            EV_SET(&events, client_fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
            // add the new connection to the events we want to monitor
            if (kevent(kq, &events, 1, NULL, 0, NULL) < 0) {
                throw KqueueException();
            }
            
        }
        else if (change_list.filter == EVFILT_READ) {
            char hello[] = "HTTP/1.1 200 OK\nContent-Type: text/plain; charset=UTF-8\nContent-Length: 15\n\nhello from meee\n";
            send(change_list.ident, hello, strlen(hello), 0);
  
        }
    }
}

using a browser i entered localhost:8090 and the program entered the

 if ((int)change_list.ident == sock) {...

the first time and then accepted the connection, went to next iteration and entered the second if condition else if (change_list.filter == EVFILT_READ) {.. (these two actions happened and i received a hello message in the browser ) but when i refreshed the browser the server just hangs with no error (which means no exceptions happen). i tried debugging and it seems like the program keeps entering the else if (change_list.filter == EVFILT_READ) {.. condition over and over until it hangs,I tried adding (naively) nev = 0 at each end of iteration to reset the events count which surely didn't resolve the problem, am i doing something wrong... ? can u give an explanation to what's happening ?

273K
  • 29,503
  • 10
  • 41
  • 64
interesting
  • 149
  • 1
  • 10
  • 1
    I don't really know kqueue but is it possible that you are entering `if (change_list.filter == EVFILT_READ)` over and over because there is still data ready to read (because you didn't read it yet) and eventually `send` blocks because the buffer is full? – user253751 Nov 17 '22 at 16:38

0 Answers0