




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第17章插 口 选 项17.1引言本章讨论修改插口行为的几个系统调用,以此来结束插口层的介绍。setsockopt和getsockopt系统调用已在第8.8节中介绍过,主要描述IP特点的选项。在本章中,介绍这两个系统调用的实现以及通过它们来的插口级选项。ioctl函数在第4.4节中已介绍过,在第4.4节中,我们描述了用于网络接口配置的与协议无关的ioctl命令。在第6.7节中,我们描述了用来分配网络掩码以及单播、多播和目的地址的IP的ioctl命令。本章介绍ioctl的实现和fcntl函数的相关特点。最后,我们介绍getsockname和getpeername系统调用,它们用来返回插口和连接的
2、 地址信息。图17-1列出了实现插口选项系统调用的函数。本章描述带阴影的函数。图17-1 setsockopt 和getsockopt 系统调用17.2代码介绍本章中涉及的源代码来自于图 17-2中列出的四个文件。图17-2 本章讨论的源文件文 件 名说明kern/kern_descrip.c kern/uipc_syscalls.c kern/uipc_socket.c kern/sys_socket.cfcntl系统调用setsockopt、getsockopt、getsockname和getpeername系统调用插口层对setsockopt和getsockopt的处理ioctl系统调用
3、对插口的处理432TCP/IP详解 卷2:实现全局变量和统计量本章中描述的系统调用没有定义新的全局变量,也没有收集任何统计量。17.3setsockopt系统调用图8-29列出了函数setsockopt (和getsockopt)能够的各种不同的协议层。本章主要集中在SOL_SOCKET级的选项,这些选项在图17-3中列出。图17-3 setsockopt 和getsockopt 选项setsockopt函数原型为:int setsockopt(int s, int level, int optname, void *optval, int optlen);图17-4显示了setsockopt
4、调用的源代码。5 6 5 - 5 9 7getsock返回插口描述符的file结构。如果val非空,则将valsize个字节的数据从进程到用m_get分配的mbuf中。与选项对应的数据长度不能超过MLEN个字节,所以,如果valsize大于MLEN,则返回EINVAL。调用sosetopt,并返回其值。图17-4 setsockopt 系统调用optnameoptval 类型变量说明S O _ S N D B U F S O _ R C V B U FS O _ S N D L O W A T S O _ R C V L O W A T S O _ S N D T I M E O S O _
5、R C V T I M E O S O _ D E B U GS O _ R E U S E A D D R S O _ R E U S E P O R T S O _ K E E P A L I V E S O _ D O N T R O U T E S O _ B R O A D C A S TS O _ U S E L O O P B A CS O _ O O B I N L I N E S O _ L I N G E RS O _ E R R O R S O _ T Y P E其他int int int intstruct timeva struct timeval intint in
6、t int int int Kintintstruct linger intintso_snd.sb_hiwat so_rcv.sb_hiwat so_snd.sb_lowat so_rcv.sb_lowat lso_snd.sb_timeo so_snd.sb_timeo so_options so_options so_options so_options so_options so_options so_optionsso_options so_linger so_error so_type缓存高水位标记接收缓存高水位标记缓存低水位标记接收缓存低水位标记超时值接收超时值插口调试信息插口能
7、重新使用一个本地地址插口能重新使用一个本地端口协议 空闲的连接旁路路由表插口支持广播报文仅用于选路域插口;进程接收的选路报文协议排队内联的带外数据 插口关闭但仍剩余数据获取差错状态并清除;只用于getsockopt获取插口类型;只用于getsockopt 返回ENOPROTOOPT433第 17 章插 口 选图17-4 (续)sosetopt函数s o s e t o p t函数处理所有插口级的选项,并将其他的选项传给与插口关联的协议的pr_ctloutput函数。图17-5列出了sosetopt函数的部分代码。图17-5 sosetopt 函数434TCP/IP详解 卷2:实现图17-5 (
8、续)7 5 2 - 7 6 4 如果选项不是插口级的(SOL_SOCKET)选项,则给底层协议PRCO_SETOPT请求。注意:调用的是协议的 pr_ctloutput函数,而不是它的pr_usrreq函数。图17-6说明了Internet协议调用的pr_ctloutput函数。图17-6 pr_ctloutput 函数7 6 5 switch语句处理插口级的选项。8 4 1 - 8 4 4 对于不认识的选项,在保存它的mbuf被后返回ENOPROTOOPT。8 4 5 - 8 5 5如果没有出现差错,则总是会执行到 switch。在switch语句中,如果协议层需要响应请求或插口层,则将选项
9、传送给相应的协议。 Internet协议中没有一个预期处理插口级的选项。注意,如果协议收到不预期的选项,则直接将其 pr_ctloutput函数的返回值丢弃。并将m置空,以免调用m_free,因为协议负责缓存。图17-7说明了linger选项和在插口结构中设置单一标志的选项。7 6 6 - 7 7 2 linger选项要求进程传入linger结构:struct linger int l_onoff;/* option on/off */int l_linger; /* linger time in seconds */;确保进程已传入长度为 l i n g e r结构大小的数据后,将结员 l
10、_ l i n g e r到so_linger中。在下一组case语句后决定是使能还是关闭该选项。 so_linger和close系统调用在第15.15节中已介绍过。7 7 3 - 7 8 9当进程传入一个非0值时,设置选项对应的标志;当进程传入的是 0时,将对应标志清除。第一次检查确保一个整数大小 (或更大)的对象在mbuf中,然后设置或清除对应的选项。图17-8显示了插口缓存选项的处理。7 9 0 - 8 1 5这组选项改变插口的和接收缓存的大小。第一个 if语句确保提供给四个选项的变量是整型。对于SO_SNDBUF和SO_RCVBUF,sbreserve只调整缓存的高水位标记而不协议pr
11、_ctloutput函数参考UDP TCPip_ctloutput tcp_ctloutput第8.8节第30.6节ICMP IGMP原始IPrip_ctloutput和ip_ctloutput第8.8节和第32.8节435第 17 章 插 口 选分配缓存。对于SO_SNDLOWAT和SO_RCVLOWAT,调整缓存的低水位标记。图17-7sosetopt函数:linger 和标志选项图17-8 sosetopt 函数:插口缓存选项436TCP/IP详解卷2:实现图17-9说明超时选项。图17-9 sosetopt函数:超时选项8 1 6 - 8 2 4进程在timeval结构中设置SO_SN
12、DTIMEO和SO_RCVTIMEO选项的超时值。如果传入的数值不正确,则返回EINVAL。8 2 5 - 8 3 0当时间间隔值的在timeval结构中的时间间隔值不能太大,因为 sb_timeo是一个短整数,为一个时钟滴答时,时间间隔值的大小就不能超过一个短整数的最大值。第826行代码是不正确的。在下列条件下,时间间隔不能表示为一个短整数:tv_usectv_sec ´ hz +> SHRT_MAXtick其中,ticck=1 000 000 /和h zSHRT_MAX=32767所以,如果下列不等式成立,则返回。SHRT_MAX tv_usec SHRT_MAX tv_u
13、sectv_sec >-=-hztick ´ hzhz100000 等式的最后一项不是代码指明的hz。正确的测试代码应该是: if (tv->tv_sec * hz+tv->tv_usec/tick>SHRT_MAX) error=EDOM;习题17.3中有更详细的讨论。8 3 1 - 8 4 0将转换后的时间, val,保存在请求的或接收缓存中。 sb_timeo限制了进程等待接收缓存中的数据或缓存中的闲置空间的时间。详细讨论参考第 16.7和16.11节。超时值是传给tsleep的最后一个参数,因为tsleep要求超时值为一个整数,所以进程最多只能等待65
14、535个时钟滴答。假设时钟频率为100 Hz,则等待时间小于11分钟。437第 17 章 插 口 选17.4getsockopt系统调用getsockopt返回进程请求的插口和协议选项。函数原型是:int getsockopt(int s, int level, int name, caddr_t val, int *valsize);该调用的源代码如图17-10所示。图17-10getsockopt 系统调用5 9 8 - 6 3 3这段代码现在看上去应该很熟悉了。 getsock获取插口的file结构,将选项缓存的大小到内核,调用 sogetopt来获取选项的值。将sogetopt返回的数
15、据到进程提供的缓存,可能还需修改缓存长度。如果进程提供的缓存不够大,则返回的数据可能会被截掉。通常情况下,选项数据的mbuf在函数返回后被。sogetopt函数同sosetopt一样, sogetopt函数处理所有插口级的选项,并将其他的选项传给与插口关联的协议。图17-11列出了sogetopt函数的开始和结束部分的代码。438TCP/IP详解卷2:实现图17-11 sogetopt 函数:概述8 5 6 - 8 7 1同s o s e t o p t一样, 函数 将那 些与 插口 级选项 无关 的选 项立 即通过PRCO_GETOPT协议请求传递给相应的协议级。协议将被请求的选项保存在 m
16、p指向的mbuf中。对于插口级的选项,分配一块标准的 mbuf缓存来保存选项值,选项值通常是一个整数,所以将m_len设成整数大小。相应的选项值通过switch语句到mbuf中。9 1 8 - 9 2 5如果执行的是 s w i t c h中的d e f a u l t情况下的语句,则mbuf,并返回ENOPROTOOPT。否则, switch语句执行完成后,将指向mbuf的指针赋给*mp。当函数返回后,getsockopt从该mbuf中将数据到进程提供的缓存,并mbuf。图17-12说明对SO_LINGER选项和作为型标志实现的选项的处理。8 7 2 - 8 7 7SO_LINGER选项请求
17、返回两个值:一个是标志值,赋给 l_onoff;另一个是拖延时间,赋给l_linger。8 7 8 - 8 8 7 其余的选项作为标志实现。将so_options和optname执行逻辑与操作,如果选项被打开,则与操作的结果为非 0值;反之则结果为 0。注意:标志被打开并不表示返回值等于1。sogetopt的下一部分代码(图17-13)将整型值选项的值到mbuf中。8 8 8 - 9 0 6将每一个选项作为一个整数到 mbuf中。注意:有些选项在内核中是作为一个短整数的(如缓存高低水位标记 ),但是作为整数返回。一旦将 so_error后,即清除so_error,这是唯一的一次getsocko
18、pt调用修改插口状态。到mbuf中439第 17 章插 口 选图17-12 sogetopt 选项:SO_LINGER 选项和选项图17-13 sogetopt 函数:整型值选项图17-14 sogetopt 函数:超时选项440TCP/IP详解 卷2:实现图17-14列出了sogetopt的第三和第四部分代码,它们的作用分别是处理SO_SNDTIMEO和SO_RCVTIMEO选项。9 0 7 - 9 1 7将或接收缓存中的 sb_timeo值赋给var。基于val中的时钟滴答数,在mbuf中构造一个timeval结构。计算tv_usec的代码有一个差错。表达式应该为: "(val
19、% h z) * tic k"。17.5fcntl和ioctl系统调用因为历史的而非有意这么做,插口API的几个特点既能通过ioctl也能通过fcntl来。关于ioctl命令,我们已经讨论了很多。我们也几次提到 fcntl。图17-15显示了本章描述的函数。 系统调用默认得到配置图17-15ioctl和fcntl的原型分别为:fcntl 和ioctl 函数int ioctl(int fd, unsigned long result, char *argp); int fcntl(int fd, int cmd,. /* int arg */);441第 17 章 插 口 选图17-1
20、6总结了这两个系统调用与插口有关的特点。我们在图 17-16中还列出了一些传统的常数,因为它们出现在代码中。考虑与P o s i x 的兼容性,可以用 O _ N O N B L O C K 来代替FNONBLOCK,用O_ASYNC来代替FASYNC。描述fcntlioctl通过打开或关闭so_state中的SS_NBIOFNONBLOCK文件状态标志FIONBIO命令来使能或非阻塞功能通过打开或关闭sb_flags中的 SB_ASYNCFASYNC文件状态标志FIOASYNC命令来使能或异步通知功能设置或得到so_pgid,它是SIGIOG和SIGURG信号的目标进程或进程组F_SETOW
21、N或F_GETOWNSIOCSPGRP或SIOCGPGRP命令得到接收缓存中的字节数;返回so_rcv.sb_ccFIONREAD返回OOB同步标记;即so_state中的SS_RCVATMARK标志SIOCATMARK图17-16fcntl 和ioctl 命令17.5.1 fcntl代码图17-17列出了fcntl函数的部分代码。图17-17 fcntl 系统调用:概况442TCP/IP详解 卷2:实现1 3 3 - 1 5 3 验证完指向打开文件的描述符的正确性后, switch语句处理请求令。2 5 3 - 2 5 7 对于不认识令, fcntl返回EINVAL。图17-18仅显示fcn
22、tl中与插口有关的代码。图17-18 fcntl 系统调用:插口处理1 6 8 - 1 8 5 F_GETFL返回与描述符相关的当前文件状态标志, F_SETFL设置状态标志。通过调用fo_ioctl将FNONBLOCK和FASYNC的新设置传递给对应的插口,而插口的新设置是通 过图17-20中描述的soo_ioctl函数来传递的。只有在第二个 fo_ioctl调用失败后,才第三次调用fo_ioctl。该调用的功能是清除FNONBLOCK标志,但是应该改为将这个标志恢复443第 17 章 插 口 选到原来的值。1 8 6 - 1 9 4 F_GETOWN返回与插口相关联的进程或进程组的标识符,
23、 so_pgid。对于非插口描述符,将TIOCGPGR Pioct l命令传给对应的 fo_ioctl函数。F_SETOWN的功能是给 so_pgid赋一个新值。17.5.2 ioctl代码我们跳过 i o c t l系统调用本身而先从 s o o _ i o c t l开始讨论,如图 17 - 20所示,因为ioctl的代码中的大部分是从图 17-17所示的代码中的。我们已经说过, soo_ioctl函数将选路命令给rtioctl,接口命令给ifioctl,任何其他令给底层协议的pr_usrreq函数。5 5 - 6 8有几个命令是由soo_ioctl直接处理的。如果*data非空,则FIO
24、NBIO打开非阻塞方式,否则关闭非阻塞方式。正于我们已经了解的,这个标志将影响到connect和close系统调用,也包括其他的读和写系统调用。a c c e p t 、6 9 - 7 9FIOASYNC使能或异步I/O通知功能。如果设置了SS_ASYNC,则无论什么时候插口上有活动,就调用sowakeup,将信号SIGIO给相应的进程或进程组。8 0 - 8 8FIONREAD返回接收缓存中的可读字节数。 SIOCSPGRP设置与插口相关的进程组,SIOCGPGRP则是得到它。 so_pgid作为我们刚讨论过的 SIGIO信号的目标进程或进程组, 当有带外数据到达插口时,则作为SIGURG信
25、号的目标进程或进程组。8 9 - 9 2 如果插口正处于带外数据的同步标记,则 SIOCATMARK返回真;否则返回假。ioctl命令,FIO输入输出空和SIO常量,有一个内部结构,如图 17-19所示。图17-19 ioctl 命令的内部结构图17-20 soo_ioctl 函数444TCP/IP详解卷2:实现图17-20(续)如果将ioctl的第三个参数作为输入,则设置input。如果该参数作为输出,则 output被宏描述返回cmd中的lengthIOCPARM_LEN(cmd) IOCBASECMD(cmd)IOCGROUP(cmd)置位。如果不用该参数,则v o i d 被置位。le
26、ngth设为0令length是参数的大小(字节)。相关令在同一返回cmd中的group个g ro u p 中但每一个命令在组中都有各自的图17-21 ioctl 命令宏number。图17-21中的宏用来中的元素。ioctl命令9 3 - 1 0 4宏IOCGROUP从命令中得到8 bit的group。接口命令由ifioctl处理。选路命令由rtioctl处理。通过PRU_CONTROL请求将所有其他令传递给插口协议。正如我们在第19章中描述的, Net/2定义了一个新的路由选择表接口,在该接口中,报文是通过一个在PF_ROUTE域中产生的插口传递给路由选择子系统。用这种方法来代替这里讨论的i
27、octl。在不兼容的内核中,rtioctl总是返回ENOTSUPP。17.6getsockname系统调用getsockname系统调用的原型是:445第 17 章 插 口 选int getsockname(int fd, caddr_t asa, int * alen);getsockname得到绑定在插口 fd上的本地地址,并将它存入 asa指向的缓存中。当在一个隐式的绑定中内核选择了一个地址,或在一个显式的 bind调用中进程指定了一个通配符地址(2.2.5节)时,该函数就很有用。getsockname系统调用如图17-22所示。图17-22 getsockname 系统调用6 8 2 - 7 1 5 getsock返回描述符的file结构。将进程指定的缓存的长度赋给len。这是我们第一次看到对m_getclr的调用:该函数分配一个标准的 mbuf,并调用bzero清零。当协议收到PRU_SOCKADDR请求时,协议处理层负责将本地地址存入 m。如果地址长度大于进程提供的缓存的长度,则返回的地址将被截掉。 *alen等于实际返回的字节数。最后,mbuf,并返回。17.7getpeername系统调用getpeername系统调用的原型是:int getpeername(int fd, cad
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 行政法学对策研究与试题及答案
- 厂区保安火灾应急预案(3篇)
- 医院氧气泄漏火灾应急预案(3篇)
- 维持经济增长的政策措施试题及答案
- 高考数学有趣题型与答案探讨
- 行政法学高效复习策略与试题
- 电梯停电火灾应急预案(3篇)
- 软件可维护性的重要性分析试题及答案
- 治疗室火灾应急预案(3篇)
- 小学夜间火灾应急预案(3篇)
- 2024年福建高考化学试卷(含答案解析)
- 2024-2025学年中职数学基础模块 下册高教版(2021·十四五)教学设计合集
- 实测实量专项方案
- 安徽彩色压花地坪施工方案
- DB34T 3620-2020 杨树立木材积表
- 小学英语四年级语法专项练习(2024年)
- 二氧化碳与水反应的实验改进
- 市政道路及综合管网工程施工组织设计
- 2024年天津市中考英语真题卷及答案
- 如果历史是一群喵
- 幼儿园名师公开课:大班艺术《漂亮的雨鞋》微课件
评论
0/150
提交评论