套接字中send和recv函数中的FLAG是什么意思?

7
在查找Linux手册页时,我发现关于套接字中发送(send)和接收(recv)格式的说明如下:

对于send函数,

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(零)。那代表什么意思?还有,在man页面中下面这行话的意思是什么?

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

然后是标志列表:

MSG_CONFIRM
MSG_DONTROUTE
.
.
.
etc.

2
这是一种常见的模式,用于避免向函数传递多个布尔参数。但我不明白你的问题是什么... - mafso
3个回答

6
如果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

我理解的是,通过按位或操作在int变量中设置特定位为1,从而设置标志位。
在代码后面,通过与特定标志位进行按位与操作,您可以知道是否设置了该标志位。

如果您指定了MSG_DONTWAIT标志,那么代码:flags & MSG_DONTWAIT将返回1,因此您知道已设置该标志。

让我们看一下MSG_DONTWAIT的定义方式。
enum
  {
    ...
    MSG_DONTWAIT    = 0x40, /* Nonblocking IO.  */
#define MSG_DONTWAIT    MSG_DONTWAIT
    ...
  };

十六进制符号0x40表示只有第七位被设置为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


3

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


2

这里有一个很好的解释,还有一个例子。

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);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接