tsockopt参数详细说明

更新时间:2023-05-08 19:30:13 阅读: 评论:0

tsockopt参数详细说明
int (
SOCKET ,
int ,
int ,
const char* ,
int
);
s(套接字): 指向⼀个打开的套接⼝描述字
level:(级别): 指定选项代码的类型。
SOL_SOCKET: 基本套接⼝
IPPROTO_IP: IPv4套接⼝
IPPROTO_IPV6: IPv6套接⼝
IPPROTO_TCP: TCP套接⼝
optname(选项名): 选项名称
optval(选项值): 是⼀个指向变量的指针 类型:整形,套接⼝结构, 其他结构类型:linger{}, timeval{ }
optlen(选项长度) :optval 的⼤⼩
返回值:标志打开或关闭某个特征的⼆进制选项
[/code:1:59df4ce128]
========================================================================
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
上⾯这两个选项影响clo⾏为
选项间隔关闭⽅式等待关闭与否
SO_DONTLINGER 不关⼼优雅否
SO_LINGER 零强制否
SO_LINGER ⾮零优雅是
若设置了SO_LINGER(亦即linger结构中的l_onoff域设为⾮零,参见2.4,4.1.7和4.1.21各节),并设置了零超时间隔,则closocket()不被阻塞⽴即执⾏,不论是否有排队数据未发送或未被确认。这种关闭⽅式称为“强制”或“失效”关闭,因为套接⼝的虚电路⽴即被复位,且丢失了未发送的数据。在远端的recv( )调⽤将以WSAECONNRESET出错。
若设置了SO_LINGER并确定了⾮零的超时间隔,则closocket()调⽤阻塞进程,直到所剩数据发送完毕或超时。这种关闭称为“优雅的”关闭。请注意如果套接⼝置为⾮阻塞且SO_LINGER设为⾮零超时,则closocket()调⽤将以WSAEWOULDBLOCK错误返回。
若在⼀个流类套接⼝上设置了SO_DONTLINGER(也就是说将linger结构的l_onoff域设为零;参见2.4,4.1.7,4.1.21节),则closocket()调⽤⽴即返回。但是,如果可能,排队的数据将在套接⼝关闭前发送。请注意,在这种情况下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丢弃数据报。
送者可以很容易地就淹没慢的接收者,导致接收⽅的UDP丢弃数据报。
SO_RCVLOWAT 接收缓冲区下限 int
SO_SNDLOWAT 发送缓冲区下限 int
每个套接⼝都有⼀个接收低潮限度和⼀个发送低潮限度。它们是函数lectt使⽤的,接收低潮限度是让lect返回“可读”⽽在套接⼝接收缓冲区中必须有的数据总量。 ——对于⼀个TCP或UDP套接⼝,此值缺省为1。发送低潮限度是让lect返回“可写” ⽽在套接⼝发送缓冲区中必须有的可⽤空间。对于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结构:
[code:1:63724de67f]
struct ip_mreq {
struct in_addr imr_multiaddr; /* IP multicast address of group */
struct in_addr imr_interface; /* local IP address of interface */
};
[/code:1:63724de67f]
若进程要加⼊到⼀个组播组中,⽤soket的tsockopt()函数发送该选项。该选项类型是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,除⾮我们的TC P选择使⽤⼀个⽐对⽅通告的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 是互相排斥的)。下⾯就让我们仔细分析下其⼯作原理。
假设应⽤程序使⽤ndfile()函数来转移⼤量数据。应⽤协议通常要求发送某些信息来预先解释数据,这些信息其实就是报头内容。典型情况下报头很⼩,⽽且套接字上设置了TCP_NODELAY。有报头的包将被⽴即传输,在某些情况下(取决于内部的包计数器),因为这个包成功地被对⽅收到后需要请求对⽅确认。这样,⼤量数据的传输就会被推迟⽽且产⽣了不必要的⽹络流量交换。
但是,如果我们在套接字上设置了TCP_CORK(可以⽐喻为在管道上插⼊“塞⼦”)选项,具有报头的
包就会填补⼤量的数据,所有的数据都根据⼤⼩⾃动地通过包传输出去。当数据传输完成时,最好取消TCP_CORK 选项设置给连接“拔去塞⼦”以便任⼀部分的帧都能发送出去。这同“塞住”⽹络连接同等重要。
总⽽⾔之,如果你肯定能⼀起发送多个数据集合(例如HTTP响应的头和正⽂),那么我们建议你设置TCP_CORK选项,这样在这些数据之间不存在延迟。能极⼤地有益于WWW、FTP以及⽂件服务器的性能,同时也简化了你的⼯作。⽰例代码如下:
intfd, on = 1;
/* 此处是创建套接字等操作,出于篇幅的考虑省略*/
tsockopt (fd, SOL_TCP, TCP_CORK, &on, sizeof (on)); /* cork */
write (fd, …);
fprintf (fd, …);
ndfile (fd, …);
write (fd, …);
ndfile (fd, …);
on = 0;
tsockopt (fd, SOL_TCP, TCP_CORK, &on, sizeof (on)); /* 拔去塞⼦ */
不幸的是,许多常⽤的程序并没有考虑到以上问题。例如,Eric Allman编写的ndmail就没有对其套接字设置任何选项。
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", "" };
tsockopt(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协议的要求和安全⽅⾯的考虑)。结果不仅是获得更快的数据传输和请求处理速度⽽且还使客户/服务器双向延迟实现了最⼩化。

本文发布于:2023-05-08 19:30:13,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/89/871133.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数据   选项   发送   连接   套接   接字   设置   服务器
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图