评论 Setsockopt选项ITeye - 牛牛娱乐

评论 Setsockopt选项ITeye

2019年02月20日08时51分46秒 | 作者: 沛白 | 标签: 选项,数据,运用 | 浏览: 2338

回复于:2003-05-08 21:20:35

  
SOL_SOCKET  
  
SO_BROADCAST 答应发送播送数据 int  
适用於 UDP socket。其意义是答应 UDP socket 「播送」(broadcast)消息到网路上。

SO_DEBUG 答应调试 int  

SO_DONTROUTE 不查找路由 int  

SO_ERROR 取得套接字过错 int  

SO_KEEPALIVE 坚持衔接 int  
检测对方主机是否溃散,防止(效劳器)永久堵塞于TCP衔接的输入。 设置该选项后,假如2小时内在此套接口的任一方向都没有数据交流,TCP就主动给对方 发一个坚持存活勘探分节(keepalive probe)。这是一个对方有必要呼应的TCP分节.它会导致以下三种状况: 对方接纳一切正常:以希望的ACK呼应。2小时后,TCP将宣布另一个勘探分节。 对方已溃散且已重新发动:以RST呼应。套接口的待处理过错被置为ECONNRESET,套接 口自身则被封闭。 对方无任何呼应:源自berkeley的TCP发送别的8个勘探分节,相隔75秒一个,企图得到 一个呼应。在宣布榜首个勘探分节11分钟15秒后若仍无呼应就抛弃。套接口的待处理错 误被置为ETIMEOUT,套接口自身则被封闭。如ICMP过错是“host unreachable(主机不 可达)”,阐明对方主机并没有溃散,可是不可达,这种状况下待处理过错被置为 EHOSTUNREACH。  



SO_DONTLINGER 若为真,则SO_LINGER选项被制止。
SO_LINGER 推延封闭衔接 struct linger  
上面这两个选项影响close行为
选项 距离 封闭办法 等候封闭与否
SO_DONTLINGER 不关心 高雅 否
SO_LINGER 零 强制 否
SO_LINGER 非零 高雅 是
若设置了SO_LINGER(亦即linger结构中的l_onoff域设为非零,拜见2.4,4.1.7和4.1.21各节),并设置了零超时距离,则closesocket()不被堵塞当即履行,不管是否有排队数据未发送或未被承认。这种封闭办法称为“强制”或“失效”封闭,由于套接口的虚电路当即被复位,且丢掉了未发送的数据。在远端的recv()调用将以WSAECONNRESET犯错。
若设置了SO_LINGER并断定了非零的超时距离,则closesocket()调用堵塞进程,直到所剩数据发送完毕或超时。这种封闭称为“高雅的”封闭。请注意假如套接口置为非堵塞且SO_LINGER设为非零超时,则closesocket()调用将以WSAEWOULDBLOCK过错回来。
若在一个流类套接口上设置了SO_DONTLINGER(也就是说将linger结构的l_onoff域设为零;拜见2.4,4.1.7,4.1.21节),则closesocket()调用当即回来。可是,假如或许,排队的数据将在套接口封闭前发送。请注意,在这种状况下WINDOWS套接口完结将在一段不断定的时间内保存套接口以及其他资源,这关于想用所以套接口的运用程序来说有必定影响。



SO_OOBINLINE 带外数据放入正常数据流,在一般数据流中接纳带外数据 int  

SO_RCVBUF 接纳缓冲区巨细 int  
设置接纳缓冲区的保存巨细
与 SO_MAX_MSG_SIZE 或TCP滑动窗口无关,假如一般发送的包很大很频频,那么运用这个选项

SO_SNDBUF 发送缓冲区巨细 int  
设置发送缓冲区的保存巨细
与 SO_MAX_MSG_SIZE 或TCP滑动窗口无关,假如一般发送的包很大很频频,那么运用这个选项
每个套接口都有一个发送缓冲区和一个接纳缓冲区。 接纳缓冲区被TCP和UDP用来将接纳到的数据一向保存到由运用进程来读。 TCP:TCP布告另一端的窗口巨细。 TCP套接口接纳缓冲区不或许溢出,由于对方不答应宣布超越所布告窗口巨细的数据。 这就是TCP的流量操控,假如对方无视窗口巨细而宣布了超越宙口巨细的数据,则接 收方TCP将丢掉它。 UDP:当接纳到的数据报装不进套接口接纳缓冲区时,此数据报就被丢掉。UDP是没有 流量操控的;快的发送者能够很容易地就淹没慢的接纳者,导致接纳方的UDP丢掉数据报。



SO_RCVLOWAT 接纳缓冲区下限 int  
SO_SNDLOWAT 发送缓冲区下限 int  
每个套接口都有一个接纳低落极限和一个发送低落极限。它们是函数selectt运用的, 接纳低落极限是让select回来“可读”而在套接口接纳缓冲区中有必要有的数据总量。 ——关于一个TCP或UDP套接口,此值缺省为1。发送低落极限是让select回来“可写” 而在套接口发送缓冲区中有必要有的可用空间。关于TCP套接口,此值常缺省为2048。 关于UDP运用低落极限, 由于其发送缓冲区中可用空间的字节数是从不改动的,只需 UDP套接口发送缓冲区巨细大于套接口的低落极限,这样的UDP套接口就总是可写的。 UDP没有发送缓冲区,只要发送缓冲区的巨细。

SO_RCVTIMEO 接纳超时 struct timeval  
SO_SNDTIMEO 发送超时 struct timeval  
SO_REUSERADDR 答应重用本地地址和端口 int  
充许绑定已被运用的地址(或端口号),能够参阅bind的man

SO_EXCLUSIVEADDRUSE
独占形式运用端口,就是不充许和其它程序运用SO_REUSEADDR同享的运用某一端口。
在断定多重绑定运用谁的时分,依据一条原则是谁的指定最清晰则将包递送给谁,并且没有权限之分,也就是说初级权限的用户是能够重绑定在高档权限如效劳发动的端口上的,这是十分严重的一个安全隐患,
假如不想让自己程序被监听,那么运用这个选项

SO_TYPE 取得套接字类型 int  
SO_BSDCOMPAT 与BSD体系兼容 int  











  
IPPROTO_IP  
  
IP_HDRINCL 在数据包中包含IP首部 int  
    这个选项常用于黑客技术中,躲藏自己的IP地址

IP_OPTINOS IP首部选项 int  
IP_TOS 效劳类型  
IP_TTL 生计时间 int  

以下IPV4选项用于组播
IPv4 选项 数据类型 描 述
IP_ADD_MEMBERSHIP struct ip_mreq 加入到组播组中
IP_ROP_MEMBERSHIP struct ip_mreq 从组播组中退出
IP_MULTICAST_IF struct ip_mreq 指定提交组播报文的接口
IP_MULTICAST_TTL u_char 指定提交组播报文的TTL
IP_MULTICAST_LOOP u_char 使组播报文环路有用或无效
在头文件中界说了ip_mreq结构:

struct ip_mreq {
 struct in_addr imr_multiaddr; /* IP multicast address of group */
 struct in_addr imr_interface; /* local IP address of interface */


若进程要加入到一个组播组中,用soket的setsockopt()函数发送该选项。该选项类型是ip_mreq结构,它的榜首个字段imr_multiaddr指定了组播组的地址,第二个字段imr_interface指定了接口的IPv4地址。
IP_DROP_MEMBERSHIP
该选项用来从某个组播组中退出。数据结构ip_mreq的运用办法与上面相同。
IP_MULTICAST_IF
该选项能够修正网络接口,在结构ip_mreq中界说新的接口。
IP_MULTICAST_TTL
设置组播报文的数据包的TTL(生计时间)。默认值是1,表明数据包只能在本地的子网中传送。
IP_MULTICAST_LOOP
组播组中的成员自己也会收到它向本组发送的报文。这个选项用于挑选是否激活这种状况。

回复于:2003-05-08 21:21:52

  
IPPRO_TCP  
  
TCP_MAXSEG TCP最大数据段的巨细 int  
获取或设置TCP衔接的最大分节巨细(MSS)。回来值是咱们的TCP发送给另一端的最大 数据量,它常常就是由另一端用SYN分节布告的MSS,除非咱们的TCP挑选运用一个比 对方布告的MSS小些的值。假如此值在套接口衔接之前取得,则回来值为未从另·—端 收到Mss选项的状况下所用的缺省值。小于此回来值的信或许真实用在衔接上,由于譬 如说运用时间戳选项的话,它在每个分节上占用12字节的TCP选项容量。咱们的TcP将 发送的每个分节的最大数据量也可在衔接存活期内改动,但条件是TCP要支撑途径MTU 发现功用。假如到对方的途径改动了,此值可上下调整。
TCP_NODELAY 不运用Nagle算法 int  

指定TCP开端发送坚持存活勘探分节前以秒为单位的衔接闲暇时间。缺省值至少有必要为7200秒,即2小时。此选项仅在SO_KEPALIVEE套接口选项翻开时才有用。

TCP_NODELAY 和 TCP_CORK,
这两个选项都对网络衔接的行为具有重要的作用。许多UNIX体系都完结了TCP_NODELAY选项,可是,TCP_CORK则是Linux体系所独有的并且相对较新;它首要在内核版别2.4上得以完结。此外,其他UNIX体系版别也有功用相似的选项,值得注意的是,在某种由BSD派生的体系上的TCP_NOPUSH选项其实就是TCP_CORK的一部分具体完结。
TCP_NODELAY和TCP_CORK基本上操控了包的“Nagle化”,Nagle化在这儿的意义是选用Nagle算法把较小的包组装为更大的帧。John Nagle是Nagle算法的发明人,后者就是用他的姓名来命名的,他在1984年初次用这种办法来测验处理福特汽车公司的网络拥塞问题(欲了解详情请参看IETF RFC 896)。他处理的问题就是所谓的silly window syndrome ,中文称“愚笨窗口症候群”,具体意义是,由于遍及终端运用程序每发作一次击键操作就会发送一个包,而典型状况下一个包会具有一个字节的数据载荷以及40个字节长的包头,所以发作4000%的过载,很轻易地就能令网络发作拥塞,。 Nagle化后来成了一种规范并且当即在因特网上得以完结。它现在现已成为缺省装备了,但在咱们看来,有些场合下把这一选项关掉也是符合需求的。
现在让咱们假定某个运用程序宣布了一个恳求,希望发送小块数据。咱们能够挑选当即发送数据或许等候发作更多的数据然后再一次发送两种战略。假如咱们立刻发送数据,那么交互性的以及客户/效劳器型的运用程序将极大地获益。例如,当咱们正在发送一个较短的恳求并且等候较大的呼应时,相关过载与传输的数据总量比较就会比较低,并且,假如恳求当即宣布那么呼应时间也会快一些。以上操作能够经过设置套接字的TCP_NODELAY选项来完结,这样就禁用了Nagle算法。
别的一种状况则需求咱们比及数据量抵达最大时才经过网络一次发送悉数数据,这种数据传输办法有益于许多数据的通讯功能,典型的运用就是文件效劳器。运用Nagle算法在这种状况下就会发作问题。可是,假如你正在发送许多数据,你能够设置TCP_CORK选项禁用Nagle化,其办法正好同TCP_NODELAY相反(TCP_CORK 和 TCP_NODELAY 是相互排挤的)。下面就让咱们仔细分析下其作业原理。
假定运用程序运用sendfile()函数来搬运许多数据。运用协议一般要求发送某些信息来预先解说数据,这些信息其实就是报头内容。典型状况下报头很小,并且套接字上设置了TCP_NODELAY。有报头的包将被当即传输,在某些状况下(取决于内部的包计数器),由于这个包成功地被对方收到后需求恳求对方承认。这样,许多数据的传输就会被推延并且发作了不必要的网络流量交流。
可是,假如咱们在套接字上设置了TCP_CORK(能够比喻为在管道上刺进“塞子”)选项,具有报头的包就会添补许多的数据,一切的数据都依据巨细主动地经过包传输出去。当数据传输完结时,最好撤销TCP_CORK 选项设置给衔接“拔去塞子”以便任一部分的帧都能发送出去。这同“塞住”网络衔接平等重要。
总而言之,假如你必定能一同发送多个数据调集(例如HTTP呼应的头和正文),那么咱们主张你设置TCP_CORK选项,这样在这些数据之间不存在推延。能极大地有益于WWW、FTP以及文件效劳器的功能,一起也简化了你的作业。示例代码如下:

intfd, on = 1;

/* 此处是创立套接字等操作,出于篇幅的考虑省掉*/

setsockopt (fd, SOL_TCP, TCP_CORK, on, sizeof (on)); /* cork */
write (fd, …);
fprintf (fd, …);
sendfile (fd, …);
write (fd, …);
sendfile (fd, …);

on = 0;
setsockopt (fd, SOL_TCP, TCP_CORK, on, sizeof (on)); /* 拔去塞子 */


不幸的是,许多常用的程序并没有考虑到以上问题。例如,Eric Allman编写的sendmail就没有对其套接字设置任何选项。

Apache HTTPD是因特网上最盛行的Web效劳器,它的一切套接字就都设置了TCP_NODELAY选项,并且其功能也深受大多数用户的满足。这是为什么呢?答案就在于完结的不同之上。由BSD衍生的TCP/IP协议栈(值得注意的是FreeBSD)在这种状况下的操作就不同。当在TCP_NODELAY 形式下提交许多小数据块传输时,许多信息将依照一次write()函数调用发送一块数据的办法发送出去。可是,由于担任恳求交给承认的记数器是面向字节而非面向包(在Linux上)的,所以引进推延的概率就下降了许多。成果只是和悉数数据的巨细有联系。而 Linux 在榜首包抵达之后就要求承认,FreeBSD则在进行如此操作之前会等候好几百个包。

在Linux体系上,TCP_NODELAY的作用同习惯于BSD TCP/IP协议栈的开发者所希望的作用有很大不同,并且在Linux上的Apache功能体现也会更差些。其他在Linux上频频选用TCP_NODELAY的运用程序也有相同的问题。


TCP_DEFER_ACCEPT

咱们首要考虑的第1个选项是TCP_DEFER_ACCEPT(这是Linux体系上的叫法,其他一些操作体系上也有相同的选项但运用不同的姓名)。为了了解TCP_DEFER_ACCEPT选项的具体思维,咱们有必要大致论述一下典型的HTTP客户/效劳器交互进程。请回想下TCP是怎么与传输数据的方针树立衔接的。在网络上,在别离的单元之间传输的信息称为IP包(或IP 数据报)。一个包总有一个带着效劳信息的包头,包头用于内部协议的处理,并且它也能够带着数据负载。效劳信息的典型比如就是一套所谓的标志,它把包符号代表TCP/IP协议栈内的特别意义,例如收到包的成功承认等等。一般,在经过“符号”的包里带着负载是完全或许的,但有时,内部逻辑迫使TCP/IP协议栈宣布只要包头的IP包。这些包常常会引发厌烦的网络推延并且还增加了体系的负载,成果导致网络功能在全体上下降。
现在效劳器创立了一个套接字一起等候衔接。TCP/IP式的衔接进程就是所谓“3次握手”。首要,客户程序发送一个设置SYN标志并且不带数据负载的TCP包(一个SYN包)。效劳器则以宣布带SYN/ACK标志的数据包(一个SYN/ACK包)作为方才收到包的承认呼应。客户随后发送一个ACK包承认收到了第2个包然后完毕衔接进程。在收到客户发来的这个SYN/ACK包之后,效劳器会唤醒一个接纳进程等候数据抵达。当3次握手完结后,客户程序即开端把“有用的”的数据发送给效劳器。一般,一个HTTP恳求的量是很小的并且完全能够装到一个包里。可是,在以上的状况下,至少有4个包将用来进行双向传输,这样就增加了可观的推延时间。此外,你还得注意到,在“有用的”数据被发送之前,接纳方现已开端在等候信息了。
为了减轻这些问题所带来的影响,Linux(以及其他的一些操作体系)在其TCP完结中包含了TCP_DEFER_ACCEPT选项。它们设置在侦听套接字的效劳器方,该选项指令内核不等候最终的ACK包并且在第1个真实有数据的包抵达才初始化侦听进程。在发送SYN/ACK包之后,效劳器就会等候客户程序发送含数据的IP包。现在,只需求在网络上传送3个包了,并且还明显下降了衔接树立的推延,对HTTP通讯而言特别如此。
这一选项在好些操作体系上都有相应的对等物。例如,在FreeBSD上,相同的行为能够用以下代码完结:

/* 为清楚起见,此处省略无关代码 */
struct accept_filter_arg af = { "dataready", "" };
setsockopt(s, SOL_SOCKET, SO_ACCEPTFILTER, af, sizeof(af));
这个特征在FreeBSD上叫做“承受过滤器”,并且具有多种用法。不过,在简直一切的状况下其作用与TCP_DEFER_ACCEPT是相同的:效劳器不等候最终的ACK包而只是等候带着数据负载的包。要了解该选项及其对高功能Web效劳器的重要意义的更多信息请参阅Apache文档上的有关内容。
就HTTP客户/效劳器交互而言,有或许需求改动客户程序的行为。客户程序为什么要发送这种“无用的”ACK包呢?这是由于,TCP协议栈无法知道ACK包的状况。假如选用FTP而非HTTP,那么客户程序直到接纳了FTP效劳器提示的数据包之后才发送数据。在这种状况下,推延的ACK将导致客户/效劳器交互呈现推延。为了断定ACK是否必要,客户程序有必要知道运用程序协议及其当时状况。这样,修正客户行为就成为必要了。
对Linux客户程序来说,咱们还能够选用另一个选项,它也被叫做TCP_DEFER_ACCEPT。咱们知道,套接字分红两种类型,侦听套接字和衔接套接字,所以它们也各自具有相应的TCP选项调集。因而,常常一起选用的这两类选项却具有相同的姓名也是完全或许的。在衔接套接字上设置该选项今后,客户在收到一个SYN/ACK包之后就不再发送ACK包,而是等候用户程序的下一个发送数据恳求;因而,效劳器发送的包也就相应减少了。

TCP_QUICKACK

阻挠因发送无用包而引发推延的另一个办法是运用TCP_QUICKACK选项。这一选项与 TCP_DEFER_ACCEPT不同,它不但能用作办理衔接树立进程并且在正常数据传输进程期间也能够运用。别的,它能在客户/效劳器衔接的任何一方设置。假如知道数据不久行将发送,那么推延ACK包的发送就会派上用场,并且最好在那个带着数据的数据包上设置ACK 标志以便把网络负载减到最小。当发送方必定数据将被当即发送(多个包)时,TCP_QUICKACK选项能够设置为0。对处于“衔接”状况下的套接字该选项的缺省值是1,初次运用今后内核将把该选项当即复位为1(这是个一次性的选项)。
在某些景象下,宣布ACK包则十分有用。ACK包将承认数据块的接纳,并且,当下一块被处理时不至于引进推延。这种数据传输形式对交互进程是适当典型的,由于此类状况下用户的输入时间无法猜测。在Linux体系上这就是缺省的套接字行为。
在上述状况下,客户程序在向效劳器发送HTTP恳求,而预先就知道恳求包很短所以在衔接树立之后就应该当即发送,这可谓HTTP的典型作业办法。已然没有必要发送一个朴实的ACK包,所以设置TCP_QUICKACK为0以进步功能是完全或许的。在效劳器方,这两种选项都只能在侦听套接字上设置一次。一切的套接字,也就是被承受呼叫直接创立的套接字则会承继原有套接字的一切选项。
经过TCP_CORK、TCP_DEFER_ACCEPT和TCP_QUICKACK选项的组合,参加每一HTTP交互的数据包数量将被下降到最小的可承受水平(依据TCP协议的要求和安全方面的考虑)。成果不仅是取得更快的数据传输和恳求处理速度并且还使客户/效劳器双向推延完结了最小化。




关于这些选项的具体状况请检查 Linux Programmers Manual

回复于:2003-05-08 21:22:17

8.2 ioctl  
ioctl能够操控一切的文件描述符的状况,这儿介绍一下操控套接字的选项.  
int ioctl(int fd,int req,...)  
  
ioctl的操控选项  
  
SIOCATMARK 是否抵达带外符号 int  
FIOASYNC 异步输入/输出标志 int  
FIONREAD 缓冲区可读的字节数 int  
  
具体的选项请用 man ioctl_list 检查.

回复于:2003-05-08 21:23:40

别的我们要注意option运用时间
如socket opt就有必要在衔接(三路握手)前

欢迎我们把自己的运用心得写上来

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表牛牛娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章