Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55483
  • 博文数量: 13
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 115
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-07 14:12
文章分类

全部博文(13)

文章存档

2015年(2)

2014年(11)

我的朋友

分类: 网络与安全

2014-12-26 10:35:56

     传输层协议使用带外数据(out-of-band,OOB)来发送一些重要的数据,如果通信一方有重要的数据需要通知对方时,协议能够将这些数据快速地发送到对方.为了发送这些数据,协议一般不使用与普通数据相同的通道,而是使用另外的通道.linux系统的套接字机制支持低层协议发送和接受带外数据.但是TCP协议没有真正意义上的带外数据.为了发送重要协议,TCP提供了一种称为紧急模式(urgent mode)的机制.TCP协议在数据段中设置URG位,表示进入紧急模式.接收方可以对紧急模式采取特殊的处理.很容易看出来,这种方式数据不容易被阻塞,可以通过在我们的服务器端程序里面捕捉SIGURG信号来及时接受数据或者使用带OOB标志的recv函数来接受.

  Intel® 主动管理技术 (Intel AMT) 就是使用的OOB.

A,TCP支持带外数据OOB?与紧急模式URG有什么关系?
     TCP
支持带外数据,但是只有一个OOB字节,TCP的带外数据是通过紧急模式URG实现的
.
B,
我们知道send(sendfd,"ABC",3,MSG_OOB),将发送3个字节的带外数据OOB数据.但是这里TCP又只支持一个字节的OOB,难道丢掉2个字节
?
     TCP将把紧急模式
URG 置位,紧急指针定位第三个字节("C")(这里不管它的具体位置,紧急指针的作用就是提供定位那个OOB字节的信息),前两个字节("AB")当作普通字节发送.其实TCP总是把最后一个字节当作OOB数据,其他的当作普通字节.不管你通过带MSG_OOB标志的sendxxx函数发送多少字节带外数据OOB数据,发送端只把最后一个字节当作OOB数据,接收端也只能收到一个字节的OOB数据
.
C,
如果一定要发送多字节的带外数据,让接收端能一次收到多个字节的带外数据.能不能做到
?
    
 对于TCP协议,不能
!
D,
对于TCP,收到的带外数据怎么保存
?
    
 两种模式
:
     1,
OOBINLINE 模式,这是套接字的默认模式,OOB字节与普通字节分开存放.存放在一个OOB缓冲区中,当然TCP只有一个字节,可以用一个字节保存OOB数据
.
     2,OOBINLINE
 模式,OOB字节和普通字节一起存放,它和普通字节本来就是一起发送,当然可以一起存放
.
E,recv(recvfd,buff,256,MSG_OOB).
会有哪些结果
?
     recvxxxx函数,在MSG_OOB模式下,将在OOB缓冲区中寻找数据。
     如果发送端没发送OOB字节,它返回错误
.
    
 如果发送端发送了OOB字节
:
     1,
对于非OOBINLINE 模式,它返回1字节的OOB数据
.
     2,
对于OOBINLINE 模式,它返回错误.因为OOB字节没有放到OOB缓冲区中
.
F,
如果发送端使用MSG_OOB模式,send(sendfd,sndbuff,64,MSG_OOB),发送了包含"OOB字节"64字节数据,然后用非MSG_OOB模式,send(sendfd,sndbuff,64,0)发送64字节,当接收端收到64+64字节的数据后,recv(recvfd,revbuff,256,0).会有哪些结果
?
1,
对于非OOBINLINE 模式,第一次recv(recvfd,revbuff,256,0)只返回前63字节的普通数据,接收缓冲区剩下64字节.要获得1字节的OOB数据,必须使用MSG_OOB模式的revxxx函数.再次recv(recvfd,revbuff,256,0),返回第二次发送的64字节.一次recvxxx不跨越urg-mark标记
.
2,
对于OOBINLINE 模式,第一次recv(recvfd,revbuff,256,0)只返回前63字节的普通数据,接收缓冲区剩下65字节(OOB+64字节),第二次recv(recvfd,revbuff,256,0),对于windows,只返回一字节的OOB字节,需要第三次rev才能返回最后的64字节,对于linux/unix,第二次rev 就返回65字节(OOB+64字节).总之与协议栈的实现有关
.
G,
如果OOB字节没被应用程序读取,协议栈又收到了新的OOB字节,会出现什么情况
?
    TCP
协议对每个socket保持一个URG指针,此时直接刷新URG指针,指向新的OOB字节
.
对于非OOBINLINE,旧的OOB字节直接被丢弃,被新的OOB字节覆盖
(经过本人测试,旧的OOB字节并不会被丢弃,而是被放入普通数据的接受缓冲区).
对于OOBINLINE,旧的OOB字节仍然在接收缓冲区中,但被当着普通数据看待,每个socket只有一个URG指针,只能定位一个OOB字节.

 

注:经测试发现,OOBINLINE是否设置带来的区别仅仅在于读取URG字节的时候是否需要MSG_OOB标志,其他包括sockatmark函数,新到OOB字节时对于尚未被读出的OOB字节的处理都是相同的。另外,即使在SIGURG处理函数中已经使用MSG_OOB读出了OOB数据,只要在普通接收缓冲区中的读指针还没有越过带外标记,OOB数据还是会被放入普通的接收缓冲区中(行为与没有读出OOB数据一样)。

阅读(1666) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~