Linux,套接字,非阻塞连接 [英] Linux, sockets, non-blocking connect
问题描述
我想创建一个非阻塞连接. 像这样:
I want to create a non-blocking connect. Like this:
socket.connect(); // returns immediately
为此,我使用了另一个线程,无限循环和Linux epoll.像这样(伪代码):
For this, I use another thread, an infinite loop and Linux epoll. Like this(pseudocode):
// in another thread
{
create_non_block_socket();
connect();
epoll_create();
epoll_ctl(); // subscribe socket to all events
while (true)
{
epoll_wait(); // wait a small time(~100 ms)
check_socket(); // check on EPOLLOUT event
}
}
如果我先运行服务器,然后运行客户端,则所有工作正常.如果我先运行客户端,请稍等一会儿,再运行服务器,然后客户端将无法连接.
If I run a server and then a client, all it works. If I first run a client, wait a some small time, run a server, then the client doesn't connect.
我做错了什么?也许可以做不同的事情吗?
What am I doing wrong? Maybe it can be done differently?
推荐答案
对于异步连接,您应该使用以下步骤:
You should use the following steps for an async connect:
- 使用
socket(..., SOCK_NONBLOCK, ...)
创建套接字
- 与
connect(fd, ...)
开始连接
- 如果返回值既不是
0
也不是EINPROGRESS
,则中止并出现错误 - 等待直到发信号通知
fd
准备输出 - 使用
getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
检查套接字的状态
- 完成
- create socket with
socket(..., SOCK_NONBLOCK, ...)
- start connection with
connect(fd, ...)
- if return value is neither
0
norEINPROGRESS
, then abort with error - wait until
fd
is signalled as ready for output - check status of socket with
getsockopt(fd, SOL_SOCKET, SO_ERROR, ...)
- done
没有循环-除非您想处理EINTR
.
No loops - unless you want to handle EINTR
.
如果首先启动客户端,则应该在最后一步看到错误ECONNREFUSED
.如果发生这种情况,请关闭插座并从头开始.
If the client is started first, you should see the error ECONNREFUSED
in the last step. If this happens, close the socket and start from the beginning.
在不查看更多详细信息的情况下很难分辨代码出了什么问题.我想,您不会因check_socket
操作中的错误而中止.
It is difficult to tell what's wrong with your code, without seeing more details. I suppose, that you do not abort on errors in your check_socket
operation.
这篇关于Linux,套接字,非阻塞连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!