《套接字选项》PPT课件.ppt

上传人:za****8 文档编号:13194060 上传时间:2020-06-07 格式:PPT 页数:49 大小:278.51KB
返回 下载 相关 举报
《套接字选项》PPT课件.ppt_第1页
第1页 / 共49页
《套接字选项》PPT课件.ppt_第2页
第2页 / 共49页
《套接字选项》PPT课件.ppt_第3页
第3页 / 共49页
点击查看更多>>
资源描述
第12章套接字选项,本章对套接字配置的获取或者设置进行介绍,通过对本章的学习将能够掌握基本的套接字属性配置方法。主要包含三个方面套接字选项、ioctl函数与套接字有关的请求命令、fcntl与套接字有关的请求命令。套接字选项介绍如下方面的知识:如何使用函数setsockopt()和函数getsockopt()。SOL_SOCKET级别套接字选项介绍。IPPTOTO_IP级别套接字选项介绍。IPPROTO_TCP级别套接字选项介绍。介绍几个进行使用套接字选项的例子。,12.1获取和设置套接字选项getsocketopt()/setsocketopt(),在进行网络编程的时候,经常需要查看或者设置套接字的某些特性,例如设置地址复用、读写数据的超时时间、对读缓冲区的大小进行调整等等操作。获得套接字选项设置情况的函数是getsockopt(),设置套接字选项的函数为setsockopt()。,12.1.1函数getsockopt()和setsocketopt()介绍,函数getsockopt()和函数setsockopt()的原型如下:#include#includeintgetsockopt(ints,intlevel,intoptname,void*optval,socklen_t*optlen);intsetsockopt(ints,intlevel,intoptname,constvoid*optval,socklen_toptlen);函数getsockopt()和函数setsockopt()的用来获取或者设置与某个套接字关联的选项。选项可能存在于多层协议中,它们总会出现在最上面的套接字层。当对套接字选项进行操作时,必须给出选项所处的层和选项的名称。为了操作套接字层的选项,应该将层的值指定为SOL_SOCKET。为了操作其它层的选项,必须给出控制选项的协议类型号。例如,为了表示一个选项由TCP协议解析,层应该设定为协议号TCP。,12.1.2套接字选项,按照参数选项级别level值的不同,套接字选项大致可以分为3类。通用套接字选项:IP选项:TCP选项:,12.1.3套接字选项简单示例,12.1.2小节中介绍了套接字的选项,本小节介绍如何使用这些套接字选项进行程序设计。下面的例子显示本系统中可能支持的套接字选项的状态,在一个程序中获得系统所支持的套接字选项的默认值,并将结果打印出来。1定义选项所用的通用数据结构2数据类型的定义3列举的套接字选项4显示查询结果disp_outcome()5主函数main()6代码的编译执行,12.2SOL_SOCKET协议族选项,SOL_SOCKET级别的套接字选项是通用类型的套接字选项,这个选项中可以命令字比较多,例如有SO_BROADCAST、SO_KEEPALIVE、SO_LINGE、SO_OOBINLINE、SO_RCVBUFF、SO_SNDBUFF等命令字对套接字的基本特性进行控制。,12.2.1SO_BROADCAST广播选项,这个选项用于进行广播设置,默认情况下系统的广播是禁止的,因为很容易误用广播的功能造成网络灾难。为了避免偶尔的失误造成意外,默认情况下套接口禁用了广播。如果确实需要使用广播功能,需要用户打开此功能。广播使用UDP套接字,其含义是允许将数据发送到子网网络的每个主机上。此项选项的输入数据参数是一个整型变量。当输入的值为0时,表示禁止广播,其他值表示允许广播。,12.2.2SO_DEBUG调试选项,SO_DEBUG调试选项表示允许调试套接字,此选项仅支持TCP,当打开此选项时,Linux内核程序跟踪在此套接字上的发送和接收的数据,并将调试信息放到一个环形缓冲区中。,12.2.3SO_DONTROUTE不经过路由选项,这个选项的设置使发出的数据分组不经过正常的路由机制。分组将按照发送数据的目的地址和子网掩码,选择一个合适的网络接口进行发送,而不用经过路由机制。如果不能有选定的网络接口确定,则会返回ENETUNREACH错误。选项设置后,网络数据不通过网关发送,只能发送给直接连接的主机或者用一个子网内的主机。可以通过将send()函数的选项设置中加上MSG_DONTROUTE标志来实现相同的效果。选项的值是布尔型整数的标识。这个选项可以在两个网卡的的局域网内使用,系统根据发送的目的IP地址,自动匹配合适的子网,例如将子网A的数据发送到网络接口B上。,12.2.4SO_ERROR错误选项,这个选项用来获得套接字错误,此套接字选项仅能够获取而不能进行设置。在Linux内核中的处理过程如下:(1)当套接字发生错误的时候,兼容BSD的网络协议将内核中的变量so_error设置为形如UNIX_Exxx的值。(2)内核通过两种方式通知用户进程:(3)进程在返回后,可以通过getsockopt的SO_ERROR选项获得发生的错误号,这个值通过一个int类型的变量获得。,12.2.5SO_KEEPALIVE保持链接选项,选项SO_KEEPALIVE用于设置TCP连接的保持,当设置此项后,连接会测试链接的状态。这个选项用于可能长时间没有数据交流的连接,通常在服务器端进行设置。当设置SO_KEEPALIVE选项后,如果在两个小时内没有数据通信时,TCP会自动发送一个活动探测数据报文,对方必须对此进行响应,通常有如下3种情况。TCP的连接正常,发送一个ACK响应,这个过程应用层是不知道的。再过两个小时,又会再发送一个。对方发送RST响应,对方在2个小时内进行了重启或者崩溃。之前的连接已经失效,套接字收到一个ECONNRESET错误,之前的套接字关闭。,12.2.6SO_LINGER缓冲区处理方式选项,选项SO_LINGER用于设置TCP连接关闭时的行为方式,就是关闭流式连接时的发送缓冲区中的数据如何处理。1SO_LINGER选项的含义2套接字关闭的过程3选项SO_LINGER的例子,12.2.7SO_OOBINLINE带外数据处理方式选项,带外数据放入正常数据流,在普通数据流中接收带外数据。当进行了此项的设置后,带外数据不再通过另外的通道获得,数据在普通数据流中可以获得带外数据。在某些情况下,发送的数据会超过所限制的数据量。通常这些数据使用不同于通常情况的接收方式来进行的,使用SO_OOBINLINE可以设置使用通用方法来接收带外数据。,12.2.8SO_RCVBUF和SO_SNDBUF缓冲区大小选项,选项SO_RCVBUF和SO_SNDBUF用于操作发送缓冲区和接收缓冲区的大小,对于每个套接字对应均有发送缓冲区和接收缓冲区。接收缓冲区用于保存网络协议栈收到的数据,直到应用程序成功的读取;发送缓冲区则需要保存发送的数据直到发送成功。,12.2.9SO_RCVLOWAT和SO_SNDLOWAT缓冲区下限选项,发送缓冲区下限选项SO_RCVLOWAT和接收缓冲区下限选项SO_SNDLOWAT用来调整缓冲区的下限值。函数select()使用发送缓冲区下限和接收缓冲区下限来判断可读和可写。当select()轮询可读的时候,接收缓冲区中的数据必须达到可写的下限值,select()才返回。对于TCP和UDP,默认的值均为1,即接收到一个字节的数据select函数就可以返回。当select()轮询可写的时候,需要发送缓冲区中的空闲空间大小达到下限值时,函数才返回。对于TCP通常为2048个字节。UDP的发送缓冲区的可用空间字节数从不发生变化,为发送缓冲区的大小,因此只要UDP套接字发送的数据小于发送缓冲区的大小,就总是可以发送的。,12.2.10SO_RCVTIMEO和SO_SNDTIMEO收发超时选项,选项SO_RCVTIMEO表示接收数据的超时时间,SO_SNDTIMEO表示发送数据的超时时间,默认情况下在接收和发送数据的时候是不会超时的,例如recv()函数当没有数据的时候会永远阻塞。这两个选项影响到的函数有如下两类:接收超时影响的5个函数为:read()、readv()、recv()、recvfrom()和recvmsg()。发送超时影响的5个函数为write()、writev()、send()、sendto()和sendmsg()。,12.2.11SO_REUSERADDR地址重用选项,这个参数表示允许重复使用本地地址和端口,这个设置在服务器程序中经常使用。例如某个服务器进程占用了TCP的80端口进行侦听,当再次在此端口侦听时会返回错误。设置SO_REUSEADDR可以解决这个问题,允许共用这个端口。某些非正常退出的服务器程序,可能需要占用端口一段时间才能允许其他进程使用,即使这个程序已经死掉,内核仍然需要一段时间才能释放此端口,不设置SO_REUSEADDR将不能正确绑定端口。,12.2.12SO_EXCLUSIVEADDRUSE端口独占选项,与SO_REUSEADDR相反,SO_EXCLUSIVEADDRUSE选项表示以独占的方式使用端口,不允许其他应用程序占用此端口,此时不能使用SO_REUSEADDR来共享使用某一个端口。选项SO_REUSEADDR可以对一个端口进行多重绑定,即如果没有使用选项SO_EXCLUSIVEADDRUSE显示的设置某一端口的不可绑定状态。多个进程可以同时绑定在某个端口上,即使调用SO_REUSEADDR的用户权限低,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是一个非常大的安全隐患,造成程序可以被很容易的监听。如果不想让程序被监听,需要使用本选项进行设置。,12.2.13SO_TYPE套接字类型选项,这个选项用于设置或者获得套接字的类型,例如SOCK_STREAM或者SOCK_DGRAM等表示套接字类型的数值。这个套接字选项经常用在忘记套接字类型或者不知道套接字类型的情况。例如,在如下的代码中先建立一个TCP套接字,但是之后忘记这个套接字的类型了,可以使用SO_TYPE选项获取其类型。s=socket(AF_INET,SOCK_STREAM,0);inttype;intlength=4;err=getsockopt(s,SOL_SOCKET,SO_TYPE,12.2.14SO_BSDCOMPAT与BSD套接字兼容选项,选项SO_BSDCOMPAT表示是否与BSD套接字兼容。目前这个选项存在一些安全漏洞,如果没有特殊的原因不要使用这个选项。例如,Linux的内核中的net/core/sock.c文件中,获得套接字选项的函数sock_getsockopt()函数中,如果设置了SO_BSDCOMPAT选项的话,其中的参数会被错误初始化并将值返回给调用的用户,导致信息泄漏。,12.2.15SO_BINDTODEVICE套接字网络接口绑定选项,套接字选项SO_BINDTODEVICE可以将套接字与某个网络设备绑定,这在同一个主机上存在多个网路设备的情况十分有用,使用这种方法,可以将某些数据显示的指定从哪个网络设备发送。,12.2.16SO_PRIORITY套接字优先级选项,套接字选项SO_PRIORITY设置通过此套接字进行发送的报文的优先级,由于Linux中发送报文队列的排队规则是高优先级的数据优先被处理,因此设置这个选项可以调整套接字的优先级。这个值通过optval来设置,优先级的范围是06(包含优先级0和优先级6)。下面的代码将套接字s的优先级设置为6。opt=6;setsockopt(s,SOL_SOCKET,SO_PRIORITY,12.3IPPROTO_IP选项,IPPROTO_IP级别的套接字选项主要是IP层协议的操作。主要包含控制IP头部选项的IP_HDRINCL、IP头部选项信息可控的IP_OPTIONS、服务类型设置的IP_TOS、IP包的生存时间设置的IP_TTL等选项控制命令字。,12.3.1IP_HDRINCL选项,一般情况下,Linux内核会自动计算和填充IP头部数据。如果套接字是一个原始套接字,设置此选项有效之后,则IP头部需要用户手动填充。用户在发送数据的时候需要手动填充IP的头部信息,这个选项通常是在需要用户自定义数据包格式的时候使用。使用此选项需要注意的是,一旦设置此选项生效,用户发送的IP数据包将不再进行分片。因此,用户的数据包不能太大,否则网卡可能不能进行发送,造成数据失败。,12.3.2IP_OPTNIOS选项,此选项允许设置IP头部的选项信息,在发送数据的时候会按照用户设置的IP选项来进行。进行IP_OPTIONS选项设置的时候,其参数是指向选项设置信息的指针和选项的长度,选项长度最大为40个字节。在TCP连接中,当进行连接的时候,如果连接信息中包含IP选项设置,则选项会自动设置为路由器包含的设置信息。在连接过程中,传入包中不能对这个选项进行更改。,12.3.3IP_TOS选项,服务类型选项,可以设置或者获取服务类型的值。,12.3.4IP_TTL选项,生存时间选项,使用此选项可以设置或者获得发送报文的TTL值。一般情况下值为64,对于原始套接字此值为255。设置IP的生存时间值,可以调整网络数据的发送速度。例如,通过一个TCP链接发送数据,如果TTL的值过大,就有各种路由方法可选。调整TCP的TTL值之后,比较长的路由路径会被取消。,12.4IPPROTO_TCP选项,IPPTOTO_TCP级别的套接字选项是对TCP层的操作。主要包括控制TCP生存时间的TCP_KEEPALIVE、最大重传时间的TCP_MAXRT、最大分节大小的TCP_MAXSEG、屏蔽nagle算法的TCP_NODELAY和TCP_CORE。,12.4.1TCP_KEEPALIVE选项,此选项用于获取或者设置存活探测的时间间隔,在SO_KEEPALIVE设置的情况下,此选项才有效。默认情况下存活时间的值为7200秒,即两个小时系统进行一次存活时间探测。下面的代码将TCP的存活时间设置为60秒钟:intalive_time=60;/*设置存活时间为60秒*/intlength_alive=sizeof(int);ints=socket(AF_INET,SOCK_STREAM,0);/*建立一个TCP套接字*/*设置新的存活时间值为60秒*/setsockopt(s,IPPROTO_TCP,TCP_KEEPALIVE,12.4.2TCP_MAXRT选项,最大重传时间,表示在连接断开之前重传需要经过的时间。此数值以秒为单位,0表示系统默认值,-1表示永远重传。下面的代码将系统的最大重传时间设置为3秒钟,如果一个TCP报文在3秒钟之内没有收到回复,则会进行数据的重传。intmaxrt=3;/*设置最大重传时间为3秒*/intlength_maxrt=sizeof(int);ints=socket(AF_INET,SOCK_STREAM,0);/*建立一个TCP套接字*/*设置新的最大重传时间值为3秒*/setsockopt(s,IPPROTO_TCP,TCP_MAXRT,12.4.3TCP_MAXSEG选项,使用此选项可以获取或设置TCP连接的最大分节大小(MSS)。返回值是TCP连接中向另一端发送的最大数据大小,它通常使用SYN与另一端协商MSS,双发的MSS选择二者提出的最小值。,12.4.4TCP_NODELAY和TCP_CORK选项,这两个选项是针对Nagle算法的关闭而设置的。1Nagle算法简介2Nagle算法的例子3选项TCP_NODELAY和TCP_CORK在Nagle算法中的作用,12.4.4TCP_NODELAY和TCP_CORK选项,12.5使用套接字选项,本节用几个例子对如何使用套接字选项进行程序设计进行说明。主要包含设置和获得缓冲区的大小、获取套接字的类型、设置套接字的读取超时时间等。,12.5.1设置和获取缓冲区大小,本小节将对设置和获取缓冲区大小的程序设计进行介绍,给出一段代码读取缓冲区大小设置的情况,然后设置缓冲区大小,再读取修改缓冲区后缓冲区的大小。1缓冲区选项使用方法2缓冲区选项使用的例子3缓冲区的内核策略,12.5.2获取套接字类型的例子,下面是一个获取套接字类型的例子,在建立一个流式套接字之后,使用getsockopt()函数的SO_TYPE命令字,获得当前套接字的类型,查看套接字的类型是否符合建立套接字的类型(流式)。,12.5.3使用套接字选项的综合例子,下面是一个综合使用套接字选项的例子,在例子中对程序设计中经常用到的套接字选项进行的使用,例如设置套接字的缓冲区大小、设置套接字的地址重用、设置套接字接收数据的超时时间等。1处理SIGPIP和SIGINT信号的函数sigpipe2服务器参数3主程序初始化部分4主函数的套接字建立5主函数的地址绑定6修改套接字缓冲区大小7修改收发的超时时间8设置服务器侦听队列长度9设置accept超时时间10select轮询客户端连接11设置客户端的超时探测时间12禁止Nagle算法13设置linger14输出客户端的信息15关闭客户端16关闭服务器端,12.6ioctl()函数,ioctl()在前面已经介绍过,是Linux下面与内核交互的一种方法,网络程序设计中广泛的使用了ioctl()函数来与内核中的网络协议栈进行交互。其函数原型为:intioctl(intd,intrequest,.);,12.6.1ioctl()命令选项,函数ioctl()的选项众多,与网络相关的总结为表12.3所示的几类,主要包含对套接字、文件、网络接口、地址解析协议(ARP)和路由等的操作请求。,12.6.2ioctl()函数的IO请求,套接字IO操作的命令请求有6个,它们的第三个参数要求为一个执行整型数据的指针。其含义如下:SIOCATMARK:SIOCSPGRP和FIOSETOWN:SIOCGPGRP和FIOGETOWN:SIOCGSTAMP:1命令SIOCATMARK的使用2命令SIOCGPGRP和FIOGETOWN的使用3命令SIOCSPGRP和FIOSETOWN的使用4命令SIOCGSTAMP的使用,12.6.3ioctl()函数的文件请求,这一组的请求命令都是FIOxxx类型,以FIO开头,除了可以处理套接字外,对通用的文件系统也同样适用。本组有三个,其含义如下:FIONBIO:FIOASYNC:FIONREAD:,12.6.4ioctl()函数的网络接口请求,网络接口的一些参数,例如IP地址、子网掩码、网络接口名称、最大传输单元等是进行网络设置或者网络程序设计的时候必须获得的参数。本小节介绍如何获得上述的参数。1网络接口的常用数据结构2获取网络接口的命令选项3网络接口的获取和配制例子,12.6.5使用ioctl()函数对ARP高速缓存操作,ARP高速缓存表是网络协议栈维护的系统运行期间的IP地址和硬件地址的映射表。其操作包括表的创建、更新、回收,在Linux下这个表的名称是arp_tbl。1获取ARP高速缓存的命令字2获取ARP高速缓存的例子,12.6.6使用函数ioctl()发送路由表请求,函数ioctl()的路由表请求有两种,这两个请求的第三个参数是一个指向结构的指针,在文件中定义。命令选项有两个:SIOCADDRT和SIOCADDRT。SIOCADDRT:向路由表中增加一项。SIOCADDRT:从路由表中减去一项。使用上面的参数没有办法列出所有的路由表中的所有项。,12.7fcntl()函数,函数fcntl()对套接字描述符进行操作,同样可以对通用文件描述符进行操作。其函数原型如下:intfcntl(intfd,intcmd,voidarg);,12.7.1fcntl()的选项,对套接字进行操作的fcntl()有四种,分为设置套接字属主、获取套接字属主、设置套接字为信号驱动类型和设置套接字为非阻塞类型。,12.7.2fcntl()修改套接字非阻塞属性,函数fcntl()的命令F_SETFL和F_GETFL命令,与O_ASYNC和O_NONBLOCK搭配可以获取或者设置套接字的非阻塞属性。常用的设置非阻塞的fcntl()操作方式的代码如下:intflags=-1;interr=-1;flags=fcntl(s,F_GETFL,0);if(flags0)printf(fcntlF_GETFLERRORn);if(!(flags,12.7.3fcntl()设置信号属主,给套接字设置属主是因为信号SIGIO和SIGURG,这两个信号需要使用命令F_SETOWN设定了进程属主才能生成。属主在第3章中已经介绍过,这里再简单介绍一下。F_SETOWN的参数arg为正数时表示绑定的为进程ID,为负数时其绝对值为进程组的ID。F_GETOWN获取的值含义与F_SETOWN一样。注意:一个套接字在使用socket()函数生成的时候是没有属主的,当服务器的accept()返回一个新的套接字描述符的时候,有了属主,其属主是从监听套接字继承来的。,12.8小结,本章介绍了如何使用函数setsockopt()和getsockopt()设置和获取套接字选项的值。这两个函数和相关的选项在调整网络的性能和功能方面起着重要的作用。套接字选项的广播参数将在高级套接字中进行介绍。套接字IP级别部分可以调整底层的性能或者一些特定的用途。例如设置了IP_HDRINCL的套接字,在接收数据和发送数据的时候,其数据包含了IP头部的数据,因此在处理时需要考虑,这是原始套接字的内容。函数ioctl和fcntl利用命令字来控制网络参数。主要包含IO命令、文件命令、网络接口命令、ARP命令及路由表命令。,
展开阅读全文
相关资源
相关搜索

当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!