我正在关注关于 kqueue 的教程(特别是http://eradman.com/posts/kqueue-tcp.html和https://wiki.netbsd.org/tutorials/kqueue_tutorial/),并且有些部分我不明白。这是我的(编辑过的)代码:
// assume internal_socket is listening
void run_server(int internal_socket) {
const int nchanges = 1;
const int nevents = BACKLOG;
struct kevent change_list[nchanges];
struct kevent event_list[nevents];
int kq = kqueue();
if (kq == -1) {
// error
}
EV_SET(&change_list, sock_internal, EVFILT_READ, EV_ADD, 0, 0, 0);
while (true) {
int nev = kevent(kq, change_list, nchanges, event_list, nevents, NULL);
if (nev == -1) {
// error
}
for (int i = 0; i < nev; ++i) {
if (event_list[i].flags & EV_EOF) {
int fd = event_list[i].ident;
EV_SET(&change_list, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
if (kevent(kq, &change_list, nchanges, NULL, 0, NULL) == -1) {
// error
}
close(fd);
} else if (event_list[i].ident == sock_internal) {
int fd = accept(event_list[i].ident, ...);
// do stuff
} else if (event_list[i].flags == EVFILT_READ) {
int bytes_read = recv(event_list[i].ident, ...);
// do stuff
}
} // for
} // while (true)
} // func
我不明白:
我是否正确设置 nevents = BACKLOG 即并发连接数?如果不是,那应该是什么?
我为什么要检查
event_list[i].flags & EV_EOF
?我最好的猜测是,如果套接字在队列中时连接失败,那么我想从队列中删除那个套接字?但是为什么我又打电话给 kevent 呢?在与前一点相同的部分中,我调用
close(fd)
. 那是对的吗?埃拉德曼教程有一些额外的巫术,但我不明白为什么。如果我理解正确,当我准备好阅读部分消息时,kqueue 可能会返回。我怎么知道消息何时完成?
如果它是相关的,我正在使用 OS X。