【问题标题】:Is select function internaly call tcp connect?选择函数内部是否调用 tcp 连接?
【发布时间】:2011-01-17 11:44:13
【问题描述】:

代码新宠物:

int CreateaTCPSocket()
{
    int iSockID =  ACE_OS::socket(......);
    ACE_OS::set_flags(iSockID,O_NONBLOCK);
    ACE_OS::bind();
    if (ACE_OS::connect(iSockID ,....) < 0)
    {
        if (ACE_OS::select(.....,timeout) <= 0)
        {
            return INVALID_HANDLE;
        }
    }
    return iSockID;
}

我的问题是当连接因非阻塞错误而失败并调用 select 并说 select return success 然后我们需要再次调用 connect 或 select function internal do connect?

【问题讨论】:

  • 请重新格式化您的问题,使代码可读。

标签: c++ c sockets ace select-function


【解决方案1】:

对于阻塞和非阻塞套接字,您只需调用一次connect()

当套接字是非阻塞的并且connect() 返回EINPROGRESS 时,它需要等到套接字准备好使用select() 进行写入。当select() 报告套接字已准备好写入时,可能是connect() 成功或失败。

要检查非阻塞connect() 是否成功,您可以调用getsockopt(..., SOL_SOCKET, SO_ERROR, ...) 以在失败时报告非零错误,或调用getpeername() 仅在连接的套接字上成功。

【讨论】:

  • 感谢您的回复,您的回答是,即使选择reurn > 0我们也需要检查它是否真的连接对吗?
  • 对,select() 不报告connect() 是否成功,只报告其结果可用。您可以跳过检查并假设connect() 已成功。在这种情况下,您稍后会在第一个send()recv() 上发现错误。
【解决方案2】:

为什么连接失败后调用 select?你想达到什么目的? select 通知调用者有关作为参数给出的资源的任何活动。这些活动可能是

  • 一个错误(例如:tcp socket: peer 断开连接)
  • 数据可用(可以在没有实际操作的情况下执行阻塞读取 阻止)
  • 可以写入(上次写入失败,缓冲区已满)

我猜在您描述的场景中,select 将始终返回 EBADF(在我知道的某些操作系统中),因为描述符尚未打开或已关闭。

马里奥

【讨论】:

  • 大多数 unix 系统的 tcp 套接字连接默认超时为 2 到 3 分钟,现在我们只需要 10 秒超时,所以首先我们将套接字设置为非阻塞,然后在连接失败时调用 select 超时...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-21
  • 2021-03-16
  • 2013-03-16
  • 1970-01-01
  • 1970-01-01
  • 2011-12-12
  • 1970-01-01
相关资源
最近更新 更多