Sockets 有人能给我一个关于';发送';非阻塞套接字的行为?
我现在已经阅读了文档至少10次,还阅读了大约10段代码片段和完整的程序,其中使用非阻塞套接字发送数据。问题是,有些教程要么是针对初学者(Beejs f.i.)的,要么在假设方面相当草率;那些不复杂的是专门的代码示例,它们不能解释为什么要这样做。即使如此,在我看来,知识库并没有完全涵盖Sockets 有人能给我一个关于';发送';非阻塞套接字的行为?,sockets,send,nonblocking,berkeley-sockets,Sockets,Send,Nonblocking,Berkeley Sockets,我现在已经阅读了文档至少10次,还阅读了大约10段代码片段和完整的程序,其中使用非阻塞套接字发送数据。问题是,有些教程要么是针对初学者(Beejs f.i.)的,要么在假设方面相当草率;那些不复杂的是专门的代码示例,它们不能解释为什么要这样做。即使如此,在我看来,知识库并没有完全涵盖send行为的所有方面。我想要的是关于f.e.的细节: 返回代码0确切地表示了什么,是否值得检查errno,还是应该在不进行进一步调查的情况下放弃连接 获取负返回值是否意味着需要关闭坏掉的连接,或者只有当errno
send
行为的所有方面。我想要的是关于f.e.的细节:
- 返回代码0确切地表示了什么,是否值得检查
,还是应该在不进行进一步调查的情况下放弃连接errno
- 获取负返回值是否意味着需要关闭坏掉的连接,或者只有当
是errno
、ewoodblock
或EAGAIN
(…其他)时才会这样做EINTR
- 当返回值为
时,是否值得检查>0
?显然,该值表示“发送”的数据量(用引号括起来,因为这确实是一个很长的过程,对不对),但由于套接字是非阻塞的,这是否意味着可以立即发出另一个调用,或者,根据errno
再次,应该等待下一个发送时机(使用select/poll/epoll)errno
- 基本上,是否先检查返回值,然后才检查
值?或者可能errno
在每次调用时设置send
,不管返回值如何?这将使错误检查更加容易errno
- 如果一个程序获得了
,那么一个程序应该采取什么好的、健壮的行为呢?只需记录状态并在下次发送时重试,如使用EINTR
和eWoldBlock
EAGAIN
- 是否同时检查
和eWoldBlock
?我们可以相信两者具有相同的价值,还是取决于实现EAGAIN
- 对于流套接字,
是否返回send
?如果没有,那么缓冲区大小就太大了,对吗EMSGSIZE
- 返回值本身是否可以等于任何一个已知错误代码
如果您能提供一个健壮的非阻塞发送代码示例,我们将不胜感激。这里有很多问题:
- 返回代码0确切地指示了什么,是否值得检查errno,还是应该在不进行进一步调查的情况下放弃连接
- 获得负的返回值是否意味着需要关闭一个坏掉的连接,或者只是这样,除非errno是ewoldblock、EAGAIN或EINTR(…其他)
- 当返回值大于0时,是否值得检查errno?显然,该值表示“发送”的数据量(在引号中,因为这是一个很长的过程,对不对),但由于套接字是非阻塞的,这是否意味着可以立即发出另一个调用,或者,根据errno的不同,应该等待下一个发送时机(使用select/poll/epoll)
- 基本上,是否先检查返回值,然后才检查errno值?或者在每次调用时发送设置errno,不管返回值如何?这将使错误检查更加容易
- 如果一个人获得了EINTR,那么对于一个程序来说,什么是好的、健壮的行为呢?只需记录状态并在下一次发送时重试,如使用eWoldBlock和EAGAIN
- 有人检查EWOULDBLOCK和EAGAIN吗?我们可以相信两者具有相同的价值,还是取决于实现
- 发送是否返回流套接字的EMSGSIZE?如果没有,那么缓冲区大小就太大了,对吗
- 返回值本身是否可以等于任何一个已知错误代码
唯一的错误代码是-1。成功是写入的字节数,因此如果您可以在32位机器上写入2^32-1字节(或在64位机器上写入2^64-1字节),这将是一个问题,但您不能写入那么多字节(如果您尝试,通常会得到一个EINVAL或EFAULT)。我将尝试回答您的问题
的返回值为0表示发送了0个字节。返回值-1表示错误。如果调用长度为0的send
,则应返回0。虽然非阻塞套接字应该返回-1,如果它将阻塞,则返回的errno为EAGAIN或eWoldBlock,但如果某些实现返回的是0字节,我不会感到太惊讶send
- EWOULDBLOCK、EAGAIN和EINTR是