我正在编写TCP / IP套接字服务器。
我的问题是,当我(例如)telnet我的服务器并且不发送任何数据时,我的接受呼叫阻塞并且不接受任何新的接入连接。
当我发送任何内容或退出telnet接受停止阻止时,我可以处理发送的数据并接受开始接受新的连接。
main() {
socket = bind_listen();
while(1) {
user_socket = accept(socket);
ssl = SSL_new(ctx);
SSL_set_fd(ssl, user_socket);
SSL_accept(ssl);
event.data.fd = user_socket;
event.events = EPOLLIN | EPOLLONESHOT;
epoll_proof = epoll_ctl(poll_fd, EPOLL_CTL_ADD, user_socket, &event);
}
}
epoll_wait()和处理数据有几个线程。 任何的想法?谢谢!
答案 0 :(得分:2)
那是因为你的程序是一个单独的线程。在第一步中,它等待连接,之后,当建立连接时,它等待输入 你有几个选项让它等待几个连接并接受它们:线程,选择和fcntl。
答案 1 :(得分:1)
您可以使用多路复用器,例如select或poll系列。
这将告诉您什么时候可以运行接受w / out被阻止。
如果您不知道如何使用多路复用器,我认为select是最简单的解决方案:http://linux.die.net/man/2/select
这也可以避免阻塞读/写等不良情况。
答案 2 :(得分:1)
首先,您应该轮询侦听文件描述符(select
,poll
或epoll
/ kqueue
)和仅调用{ {1}}如果它已准备好阅读。
其次,更具体地说,如果您要使用边缘触发accept
,则需要先将套接字设置为非阻塞模式。然后,当您被告知已准备好阅读时,您需要循环调用epoll
,直到您返回accept
,错误为-1
或EAGAIN
- 可能是多个连接请求一次等待,边缘触发轮询仅警告您状态更改,因此您需要耗尽套接字。
以一种非常天真的方式, 也可以取消轮询,仅使用非阻塞套接字,无论是在繁忙的循环中还是在循环中有点睡觉但这完全是浪费,与适当的EWOULDBLOCK
/ epoll
解决方案(或您的平台提供的任何轮询机制)相比,并没有给您带来任何好处。