为什么 fcntl() 标志值以八进制格式定义以及此函数如何用于 blocking/non-blocking 套接字?
Why fcntl() flag values are defined in Octal format & how this function works for blocking/non-blocking sockets?
// "fcntl-linux.h" (with few lines skipped):
/* open/fcntl. */
#define O_ACCMODE 0003
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_APPEND 02000
#define O_NONBLOCK 04000
#define O_SYNC 04010000
只要在“0”之后提到一个数字,它就会变成 八进制 表示法。选择不太传统的 "Octal" 格式而不是更流行的十进制或十六进制的原因是什么?
this answer 是从非阻塞到阻塞套接字的正确方法吗?
fcntl(socket, F_GETFL, 0)
和fcntl(socket, F_GETFL)
有区别吗?
[注意:当我将套接字设置为非阻塞模式时,SSL 连接不起作用。在阻塞模式下它工作正常。因此,描述模式设置的代码示例会很好(如果它与链接代码不同)。]
没有真正的原因。如果它们是十进制的,它们也能正常工作;电脑不关心。
一般来说,"older" 组标志通常以八进制定义,因为它们可以追溯到八进制比十六进制更流行的时代。有人可能会猜到打开的标志可能是从其他一些 OS 复制而来的,它们是八进制的。
"Why fcntl() flag values are defined in Octal format"
正如许多用户所建议的那样,这纯粹是因为历史原因。显然八进制格式比十六进制格式更 流行 。
"Is this answer the correct way to make non-blocking to blocking socket?"
是。答案是正确的,因为它的目的是在考虑各种情况的情况下设置标志。但是,错误检查会更有帮助,这是微不足道的。
"Is there a difference between fcntl(socket, F_GETFL, 0)
and fcntl(socket, F_GETFL)
?"
没有区别。 man page for fcntl(2) 建议相同。
F_GETFL (void) -- Get the file access mode and the file status flags; arg is ignored.
使用非阻塞套接字的 SSL 连接
这是一个有点棘手的部分,我遇到了问题。典型的 SSL 阻塞调用如下所示:
int result = ::SSL_connect(pSSL); // <0: failed, 0: disconnected, 0<: pass
现在,自然的非阻塞替代方案,我们可以假设为:
::fcntl(socketfd, F_SETFL, m_fcntl);
::connect(socketfd, ...);
int result == ::SSL_connect(pSSL);
// put the FD_SET() etc.
result = select(...);
if(result == 0) ... // SSL timed out
else if(result < 0) ... // SSL error
else ... // success
然而,它并没有这么简单。 SSL 是一个有点复杂的过程,其中来回交换消息。因此,我们必须运行 ::SSL_Connect()
循环捕获SSL_want_read, SSL_want_write
。以简单的方式,代码可能如下所示:
::fcntl(socketfd, F_SETFL, m_fcntl);
::connect(socketfd, ...);
int result; // looping for various handshakes & to/from messages
while((result = ::SSL_connect(pSSL)) < 0) {
// put the FD_SET() etc.
if(select(...) <= 0)
break;
}
if(result == 0) ... // SSL timed out
else if(result < 0) ... // SSL error
else ... // success
我能够用上面的(伪)代码解决我的 SSL 问题。
此答案基于有用的评论和我的发现。
// "fcntl-linux.h" (with few lines skipped):
/* open/fcntl. */
#define O_ACCMODE 0003
#define O_RDONLY 00
#define O_WRONLY 01
#define O_RDWR 02
#define O_APPEND 02000
#define O_NONBLOCK 04000
#define O_SYNC 04010000
只要在“0”之后提到一个数字,它就会变成 八进制 表示法。选择不太传统的 "Octal" 格式而不是更流行的十进制或十六进制的原因是什么?
this answer 是从非阻塞到阻塞套接字的正确方法吗?
fcntl(socket, F_GETFL, 0)
和fcntl(socket, F_GETFL)
有区别吗?
[注意:当我将套接字设置为非阻塞模式时,SSL 连接不起作用。在阻塞模式下它工作正常。因此,描述模式设置的代码示例会很好(如果它与链接代码不同)。]
没有真正的原因。如果它们是十进制的,它们也能正常工作;电脑不关心。
一般来说,"older" 组标志通常以八进制定义,因为它们可以追溯到八进制比十六进制更流行的时代。有人可能会猜到打开的标志可能是从其他一些 OS 复制而来的,它们是八进制的。
"Why fcntl() flag values are defined in Octal format"
正如许多用户所建议的那样,这纯粹是因为历史原因。显然八进制格式比十六进制格式更 流行 。
"Is this answer the correct way to make non-blocking to blocking socket?"
是。答案是正确的,因为它的目的是在考虑各种情况的情况下设置标志。但是,错误检查会更有帮助,这是微不足道的。
"Is there a difference between
fcntl(socket, F_GETFL, 0)
andfcntl(socket, F_GETFL)
?"
没有区别。 man page for fcntl(2) 建议相同。
F_GETFL (void) -- Get the file access mode and the file status flags; arg is ignored.
使用非阻塞套接字的 SSL 连接
这是一个有点棘手的部分,我遇到了问题。典型的 SSL 阻塞调用如下所示:
int result = ::SSL_connect(pSSL); // <0: failed, 0: disconnected, 0<: pass
现在,自然的非阻塞替代方案,我们可以假设为:
::fcntl(socketfd, F_SETFL, m_fcntl);
::connect(socketfd, ...);
int result == ::SSL_connect(pSSL);
// put the FD_SET() etc.
result = select(...);
if(result == 0) ... // SSL timed out
else if(result < 0) ... // SSL error
else ... // success
然而,它并没有这么简单。 SSL 是一个有点复杂的过程,其中来回交换消息。因此,我们必须运行 ::SSL_Connect()
循环捕获SSL_want_read, SSL_want_write
。以简单的方式,代码可能如下所示:
::fcntl(socketfd, F_SETFL, m_fcntl);
::connect(socketfd, ...);
int result; // looping for various handshakes & to/from messages
while((result = ::SSL_connect(pSSL)) < 0) {
// put the FD_SET() etc.
if(select(...) <= 0)
break;
}
if(result == 0) ... // SSL timed out
else if(result < 0) ... // SSL error
else ... // success
我能够用上面的(伪)代码解决我的 SSL 问题。
此答案基于有用的评论和我的发现。