9

我有一组保持活动状态的 TCP 套接字(间隔 1 分钟),由select(2) 循环控制(选择读取)。

  • select(2)如果 set 中的一个套接字发生 keep-alive 超时,是否会返回错误?
  • 哪个错误会read(2)返回?
4

2 回答 2

5

  • select()如果为它选择的套接字之一发出错误信号,它本身不会返回错误。[事实上,API 不能以这种方式指示每个套接字的错误,因为两个不同的套接字可能在一次调用select(). 哪个会select()回来?】
  • 在循环的每次迭代之后,您改为使用 FD_ISSET 宏在每个标记为可读的套接字上select()尝试 a 。read()
  • 任何时候套接字设置了挂起的错误,它的读取事件(和写入事件)都会发出信号并select()返回,允许您立即获取由于保持活动而导致的超时错误。请注意,选择将套接字标记为读取并不表示有数据要读取,只是表示尝试读取不会阻塞。如果套接字有待检索的未决错误,则读取不会阻塞。在尝试处理任何数据之前,两者都read(2)首先检索套接字上的任何未决错误。write(2)

    当对带有 O_NONBLOCK 清除的输入函数的调用不会阻塞时,无论该函数是否会成功传输数据,都应认为描述符已准备好读取。(该函数可能返回数据、文件结束指示或指示它被阻塞的错误以外的错误,并且在每种情况下,描述符应被视为已准备好读取。) [ POSIX:select() ]

  • 最后返回什么错误?至关重要的是,这取决于 keepalive 是如何失败的。ETIMEDOUT如果另一端完全消失,你会得到。如果发生数据包传递错误,您将通过它来代替(因此,如果保持活动数据包收到 ICMP 错误回复,例如“主机不可达”,您将已经EHOSTUNREACH交付)。[有关这些情况的更多详细信息,请参阅 Stevens,“Unix Network Programming, vol 1”。]

于 2012-12-12T13:43:30.747 回答
1

select()在 中设置一个位FDSET ,指示哪个套接字已触发。使用FD_ISSET宏来确定哪个套接字请求服务。

于 2012-12-12T13:11:59.130 回答