引言
一般来说我们使用recv的时候第四个参数都设置为0,所以才有了read和recv差不多的说法,那么第四个参数有什么用呢?在我遇到这个问题的时候查询CSDN无果,遂在解决后进行记录,以帮助有同样需求的朋友。
正文
第四个参数可以使用0或者以下类型的组合:
-
MSG_DONTROUTE
:send函数使用,告诉IP协议,目的主机在本地网络上,不需要查找路由表。 -
MSG_OOB
:可以接收和发送带外数据,没记错的话TCP的数据包中六个标记位中就有这样一个标记位,即URG。 -
MSG_PEEK
:表示只是从缓冲区读取内容而不清除缓冲区,也就是说下次读取还是相同的内容,多进程需要读取相同数据的时候可以使用。 -
MSG_WAITALL
: 表示收到了所有数据的时候才从阻塞中返回,使用这个参数的时候,如果没有收到的数据没有达到我们的需求,就会一直阻塞,直到条件满足。想到了大一写聊天室接收文件时就用这个参数偷懒的哈哈哈。
我们可以在socket.h中看到一个如下的枚举体:
enum
{
MSG_OOB = 0x01, /* Process out-of-band data. */
MSG_PEEK = 0x02, /* Peek at incoming messages. */
MSG_DONTROUTE = 0x04, /* Don't use local routing. */
/* DECnet uses a different name. */
MSG_TRYHARD = MSG_DONTROUTE,
MSG_CTRUNC = 0x08, /* Control data lost before delivery. */
MSG_PROXY = 0x10, /* Supply or ask second address. */
MSG_TRUNC = 0x20,
MSG_DONTWAIT = 0x40, /* Nonblocking IO. */
MSG_EOR = 0x80, /* End of record. */
MSG_WAITALL = 0x100, /* Wait for a full request. */
MSG_FIN = 0x200,
MSG_SYN = 0x400,
MSG_CONFIRM = 0x800, /* Confirm path validity. */
MSG_RST = 0x1000,
MSG_ERRQUEUE = 0x2000, /* Fetch message from error queue. */
MSG_NOSIGNAL = 0x4000, /* Do not generate SIGPIPE. */
MSG_MORE = 0x8000, /* Sender will send more. */
MSG_WAITFORONE = 0x10000, /* Wait for at least one packet to return.*/
MSG_BATCH = 0x40000, /* sendmmsg: more messages coming. */
MSG_ZEROCOPY = 0x4000000, /* Use user data in kernel path. */
MSG_FASTOPEN = 0x20000000, /* Send data in TCP SYN. */
MSG_CMSG_CLOEXEC = 0x40000000 /* Set close_on_exit for file
descriptor received through
SCM_RIGHTS. */
};
说实话,文档确实不多,这里面很多都很难查到资料,但可以确定不全是用与recv的,有一些用于UDP的recvfrom,sendto的,比如MSG_PROXY,MSG_TRUNC等。
参考:
- 博文《TCP带外数据OOB》
- 问答《using flags MSG_TRUNC , MSG_CTRUNC in UDP socket [closed]》
- 博文《MSG_PROXY not working to provide/specify alternate addresses for transparent proxying》