荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: everlove.bbs@bbs.shuoshuo.net (我是如此厌倦), 信区: Linux
标  题: unp第二十一章学习体会
发信站: 寂寞森林 (Mon Sep 23 10:53:38 2002)
转信站: SZUBBS!news2.happynet.org!news.happynet.org!LonelyWood


发信人: clown (梧桐叶), 信区: UNP
标  题: unp第二十一章学习体会
发信站: UNIX编程 (2001年10月12日20:17:10 星期五), 站内信件

本章介绍的是带外数据(out-of-band data),我对带外数据
没有什么了解,只是接触过紧急模式,幸好书上认为这两个概念
认为是等同的。但是在TCP/IP Illustrated中又说,“许多实现
不正确地称TCP的紧急模式为带外数据”,我也不太明白到底真正
的带外数据是什么呢?

在这里,我暂且将紧急模式认为是带外数据,下面的介绍就以紧急
模式为例。

1)概念
在TCP头部,有一个紧急标志,发送方用它来通知接收方具有某种
方式的“紧急数据”已经放置在普通的数据流中,由接收方决定如何
处理。与该标志相对应,有一个紧急指针(与序列号配合计算紧急偏
移),用来指示紧急数据的位置,一般该指针有一个比用MSG_OOB标志
写入的数据多一个字节的序列号。只要接收方当前读取位置到紧急数
据指针之间有数据存在,就认为应用程序处于“紧急模式”。

2)紧急模式的特点
主要是在接收方TCP缓冲区没有空间的情况下,紧急通知也会发送到对方。
另外,紧急指针总是指向刚好越过紧急数据的后一个字节的地方。当使用
recv函数读去接收套接口内容时,总是会停留在紧急指针处。

3)紧急数据的发送和接收
发送的时候,只需要将send函数的flag标志设置为MSG_OOB。
接收相对来说要复杂一些,有三种不同的方法来接收紧急数据:

1。使用SIGURG信号接收紧急数据
首先建立信号处理函数,然后使用fcntl设置套接口的属主,这样当紧急
数据到达时,套接口的属主就会收到SIGURG信号,然后使用recv函数,将
flag标志设置为MSG_OOB就可以了。

2。使用select函数
当带外数据到达时,select会返回一个异常,在异常条件中调用recv函数
就可以接收紧急数据了。

3。使用sockatmark函数
当紧急数据到达时,该函数返回1。虽然Linux不支持该函数,但是使用
ioctl的SIOCATMARK选项可以很简单地实现。

有一个要注意的问题是,当由紧急指针指向的实际数据字节到达接收者的
tcp缓冲区时,这个数据字节并没有存放在套接口缓冲区,而是被放到这个
连接的单独的1字节带外缓冲区。进程从这个特别的1字节缓冲区读取数据
的仅有办法是调用recv, recvfrom或者recvmsg并且指定MSG_OOB标志。
然而如果设置了SO_OOBONLINE套接口选项,那么紧急指针指向的实际数据
就保存在套接口缓冲区中,进程不能指定MSG_OOB选项。

书中最后介绍了一个使用紧急模式来实现客户-服务器心博函数例子,觉得
很实用。

下面有一个测试紧急模式的例子:
客户发送了四个数据报,其中有两个时紧急模式。通过tcpdum可以明显地看到。
服务器端的结果出人意料,当recv的时候,一次就将所有的数据全部接收了,
但是显示的缓冲区数据确只指示到第一个紧急指针的位置,然后就此一个
紧急模式标志,接着再recv的时候程序就退出了。



--
易朽的是生命,似那转瞬即谢的花朵;然而永存的,是对未来的渴望,
是那生生世世传递下来的,不朽的,生的激情。每一朵勇敢开放的花,
都是一个死亡唇边的微笑。
※ 修改:·clown 於 10月12日20:21:54 修改本文·[FROM: 211.69.205.23]
※ 来源:·UNIX编程 www.tiaozhan.com/unixbbs/·[FROM: 211.69.205.23]


--
我站在夜的尽头
窗外的雨悄悄坠落





※ 来源:.寂寞森林 http://bbs.shuoshuo.net  ◆ FROM: 211.161.158.231


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店