连接完成之前非阻塞 TCP 套接字上的 recv 行为

发布于 2024-09-29 13:46:06 字数 288 浏览 6 评论 0原文

朋友们,

我有一个非阻塞 TCP 套接字(在 AIX 上)。当我尝试 connect() 时,我得到了 EINPROGRESS。我的问题是,如果我在连接完成之前调用recv(),(最合适的)错误代码是什么?

我看到,如果连接失败,我调用recv(),我会得到ECONNREFUSED;意味着我收到了与之前的 connect() 尝试相对应的错误。采用相同的逻辑,我应该得到recv()的EINPROGRESS。我的方法正确吗?

如果是,这就提出了另一个问题——为什么这样的错误代码不包含在recv()的错误代码中?

Friends,

I have a non-blocking TCP socket (on AIX). When I attempted connect() I got EINPROGRESS. My question is if I call recv() before connection completion, what would be the (most apprpriate) error code?

I saw that, in case connection fails, and I call recv(), I got ECONNREFUSED; means I got an error corresponding to my earlier connect() attempt. Taking same logic I should get EINPROGRESS for recv(). Am I right in my approach ?

If yes, this raises another question - Why such error codes are not included amongst error codes of recv()?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只有一腔孤勇 2024-10-06 13:46:06

在这种情况下,我只看到返回了 EAGAIN,就像您在没有数据可读取的情况下看到的那样。对于写入未连接的套接字,您通常会得到 ENOTCONN,尽管我相信某些平台可能会给您 EAGAIN。

这是一个简单的 Python 脚本来演示:

import socket
# Any address that does not succeed or fail right away will do
ADDR = "192.168.100.100"
PORT = 23
s = socket.socket()
s.setblocking(False)
try:
    s.connect((ADDR, PORT))
except socket.error, e:
    print "Connect gave us",e
try:
    s.recv(1)
except socket.error, e:
    print "Read gave us",e
try:
    s.send("x")
except socket.error, e:
    print "Write gave us",e

对我来说,它给出了:
Connect 给了我们(36,“操作正在进行中”)
Read 给了我们(35,“资源暂时不可用”)
Write 给了我们(57,'Socket 未连接'),

它们分别是 EINPROGRESS、EAGAIN 和 ENOTCONN。

I have only seen EAGAIN returned in this case, just as you would see in the case where there's no data to read. For writing to a non-connected socket, you typically get ENOTCONN, though I believe some platforms might give you EAGAIN.

Here's a trivial Python script to demonstrate:

import socket
# Any address that does not succeed or fail right away will do
ADDR = "192.168.100.100"
PORT = 23
s = socket.socket()
s.setblocking(False)
try:
    s.connect((ADDR, PORT))
except socket.error, e:
    print "Connect gave us",e
try:
    s.recv(1)
except socket.error, e:
    print "Read gave us",e
try:
    s.send("x")
except socket.error, e:
    print "Write gave us",e

For me, it gives:
Connect gave us (36, 'Operation now in progress')
Read gave us (35, 'Resource temporarily unavailable')
Write gave us (57, 'Socket is not connected')

These are EINPROGRESS, EAGAIN, and ENOTCONN respectively.

鸠魁 2024-10-06 13:46:06

您正在非阻塞套接字上进行操作,这非常适合返回 EINPROGRESS,这表明连接建立尚未完成,这在 connect 页面中进行了记录:

   EINPROGRESS
          The  socket  is  nonblocking  and  the  connection cannot be completed immediately.  It is possible to select(2) or poll(2) for completion by
          selecting the socket for writing.  After select(2) indicates writability, use getsockopt(2) to read the SO_ERROR option at  level  SOL_SOCKET
          to  determine  whether connect() completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed
          here, explaining the reason for the failure).

因此您将需要 select/pool 来确保套接字已 完成可写,并从 SO_ERROR 中获取错误。

You are operating on a non-blocking socket, which is perfect fine to return EINPROGRESS, which indict that the connection establishment has not being finished yet, this is documented in connect's page:

   EINPROGRESS
          The  socket  is  nonblocking  and  the  connection cannot be completed immediately.  It is possible to select(2) or poll(2) for completion by
          selecting the socket for writing.  After select(2) indicates writability, use getsockopt(2) to read the SO_ERROR option at  level  SOL_SOCKET
          to  determine  whether connect() completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual error codes listed
          here, explaining the reason for the failure).

So you will need select/pool to make sure the socket is writable, and get error from SO_ERROR.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文