【发布时间】:2017-05-03 08:58:17
【问题描述】:
我正在关注关于 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)。那是对的吗? eradman 教程有一些额外的巫术,但我不明白为什么。如果我理解正确,当我准备好阅读部分消息时,kqueue 可能会返回。我如何知道消息何时完成?
如果相关,我正在使用 OS X。
【问题讨论】: