socket send 和 recv 中 FLAG 的含义

Posted

技术标签:

【中文标题】socket send 和 recv 中 FLAG 的含义【英文标题】:Meaning of FLAG in socket send and recv 【发布时间】:2014-08-17 07:24:44 【问题描述】:

在Linux手册页中搜索时,我发现socket中send和recv的格式如下:

对于发送,

ssize_t send(int sockfd, const void *buf, size_t len, int flags);

对于recv,

ssize_t recv(int sockfd, void *buf, size_t len, int flags);

但我不确定他们想表达什么int flags。在一个示例代码中,我发现 flag 的值为 0(零)。这是什么意思?手册页下面一行的含义是什么?

"The flags argument is the bitwise OR of zero or more of the following flags."

然后是标志列表:

MSG_CONFIRM
MSG_DONTROUTE
.
.
.
etc.

【问题讨论】:

这是避免将多个布尔参数传递给函数的常见模式。但我不明白你的问题是什么…… 【参考方案1】:

如果int flags 等于0,则表示没有指定标志。这些是可选的。 回答有关 ORing 标志的问题 - 这是一种允许您指定多个标志的机制 - MSG_CONFIRM | MSG_DONTWAIT 指定两个标志。

OR gate:          AND gate:

a b  out          a b  out
0 0  0            0 0  0
0 1  1            0 1  0
1 0  1            1 0  0
1 1  1            1 1  1

我的理解是,通过 ORing 标志,您将 int 变量中的特定位设置为 1。 稍后在代码中,通过将该变量与特定标志进行与运算,您可以知道标志是否已设置。 如果您指定了MSG_DONTWAIT 标志,则代码:flags & MSG_DONTWAIT 将返回 1,因此您知道该标志已设置。 让我们看看 MSG_DONTWAIT 是如何定义的。

enum
  
    ...
    MSG_DONTWAIT    = 0x40, /* Nonblocking IO.  */
#define MSG_DONTWAIT    MSG_DONTWAIT
    ...
  ;

十六进制符号0x40 表示只有第 7 位设置为 1。 下面我展示了一个来自 socket.c 的按位运算示例。在创建套接字文件描述符时检查是否设置了O_NONBLOCK 标志。如果是,则将当前标志变量的第 7 位设置为 1,即定义为 MSG_DONTWAIT

if (sock->file->f_flags & O_NONBLOCK)
    flags |= MSG_DONTWAIT;

关于按位运算的不错参考:http://teaching.idallen.com/cst8214/08w/notes/bit_operations.txt

【讨论】:

【参考方案2】:

Here 的解释很好,有一个例子。

0 标志允许您使用具有标准行为的常规 recv()。 如果您想使用自定义的 recv(),您需要将您的标志(手册页中列出的那些)与 OR 运算符分开,如下所述:

"The flags argument is the bitwise OR of zero or more of the following flags."

就这样:

recv(sockfd, buf, buflen, FLAG | FLAG | FLAG);

【讨论】:

【参考方案3】:

标志允许传递额外的行为。默认值 (0) 将导致默认行为。在大多数简单的情况下,这就是您想要的。 如果您希望网络子系统以特定方式运行,您可以通过 Oring 传递标志值或多个值:例如,如果您想要“MSG_DONTWAIT”和“MSG_MORE”行为(如手册页所述)你可以使用MSG_DONTWAIT | MSG_MORE

【讨论】:

以上是关于socket send 和 recv 中 FLAG 的含义的主要内容,如果未能解决你的问题,请参考以下文章

read VS recv?关于 send 和 recv 的第四个参数 flag

socket编程·send和recv

socket通信中send()和recv()的行为

Socket send函数和recv函数详解

ZMQ:socket_send/recv 阻塞

Socket send函数和recv函数详解