socket函数中带外数据(MSG_OOB)Flag是什么意思?

回顾socket读写系列调用

当从socket读取数据时,通常会用到read/write系列函数。由于读写函数都是配对的,这里以read系列为例,通过man手册可以看到:

ssize_t read(int fd, void *buf, size_t count);

ssize_t readv(int fd, const struct iovec *iov, int iovcnt);

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

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,

struct sockaddr *src_addr, socklen_t *addrlen);

ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);

这些函数最主要的区别,一方面是可以通过提供了Flag参数来设置特性;另一方面是支持更高效的“离散读或聚集写”(scatter input or gather output)结构操作buffer。本期讲解的就是Flag参数中的MSG_OOB。

socket函数Flag参数之MSG_OOB

实际上大多数应用可能不会使用到函数中提供的flag参数,这里介绍MSG_OOB,在telnet、ftp应用中有使用到。

MSG_OOB是用来设置接受“带外数据”(out-of-band data),用于告知应用层处理较为紧急的数据。这个特性的底层逻辑是由于TCP的协议头中的FLAG有URG标志;再配合紧急指针标记紧急的数据是什么,紧急数据限制为1个字节。如果忘记了TCP的协议头,可以回顾下:


socket函数中带外数据(MSG_OOB)Flag是什么意思?

TCP协议头


默认情况下,带外数据是存放在专门的⼀个字节的带外数据缓冲区中的。⼀个tcp连接只有⼀个带外数据,第⼆个到来的带外数据会覆盖第⼀个到来的带外数据。在获取带外数据的时候,一般按如下的编程逻辑:

1、通过信号处理SIGURG,过程⾸先设置⽂件描述字的进程属主:

fcntl(sockfd, F_SETOWN,getpid())

2、然后注册SIGURG信号处理句柄并且在句柄⾥⾯读取带外数据

这里以一个服务器/客户端的例子来测试下,server端的代码如下:

socket函数中带外数据(MSG_OOB)Flag是什么意思?

server端

客户端的代码:


socket函数中带外数据(MSG_OOB)Flag是什么意思?

client端


输出如下:


socket函数中带外数据(MSG_OOB)Flag是什么意思?

输出

通过抓包分析我们可以看到,server端按照client中的代码先收到普通数据,然后收到带有URG标志的数据;收到带有URG标志的包触发了server端的OOB函数。

socket函数中带外数据(MSG_OOB)Flag是什么意思?

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章