套接字选项

有几个函数可以设置影响套接字的选项

  • getsockopt 和 setsockopt函数
  • fcntl 函数
    • 把套接字设为非阻塞
    • 信号驱动式I/O中设置套接字属主(进程)
  • ioctl函数
getsockopt函数 和 setsockopt函数
#include <sys/socket.h>

int setsockopt(int sockfd, int leval, int opename, const void* optval, socklen_t optlen);
    函数返回值:若成功则为0,若出错则为-1。

int getsockopt(int sockfd, int level, int optname, void* optval, socklen_t *opelen);
    函数返回值:若成功则为0,若出错则为-1。
  • 参数sockfd
    指向一个打开的套接字描述符。

  • 参数level
    表示级别,解释选项的代码作用于通用套接字,或为作用域某个特定的协议套接字。

  • 参数*optval
    optval 是一个指向某个变量的指针,stesockopt从*optval中取得选项待设置的新值,getsockopt则把获取的值保存在这个变量中。

  • 参数*opelen 或 optlen
    optlen指定选项*optval的大小。

    eg:  setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));  // 开启经受时延算法
    

    *opelen是一个指向某个地址的指针,其所指

套接字选项
  • level
    #include <netinet/in.h>
    
    #include <netinet/tcp.h>
    
  • optname
    #include <netinet/in.h>
    
    #include <netinet/tcp.h>
    
  • 标志
    套接字选项可以粗分为2类:
    • 启用或禁止某个特性的二元选项,称为标志选项。
    • 取得并返回我们可以设置或检查的特定值的选项,称为值选项。
level optname get set 说明 标志 数据类型
SOL_SOCKET SO_KEEPALIVE 周期性的检测连接是否存活 int
SOL_SOCKET SO_RCVBUF 接收缓冲区的大小 int
SO_SNDBUF 发送缓冲区的大小 int
SO_RCVTIMEO 接收超时 timeval{}
SO_SNDTIMEO 发送超时 timeval{}
SO_REUSEADDR 允许重用本地地址 int
SO_REUSEPORT 允许重用本地端口 int
IPPROTO_IP
IPPROTO_TCP TCP_NODELAY 禁止Nagle算法 int
SO_KEEPALIVE 套接字选项

给一个套接字设置保持存活(keep-alive)选项后,如果在2小时内在该套接字的任一方向上都没有数据交换,TCP就自动给对端发送一个保持存活探测分节, 这是一个对端必须响应的分节,会导致下列3种情况:

  • 对端以期望的ACK回应,应用进程得不到通知。在又经过2小时后,TCP将发出新的探测分节。
  • 对端以RST响应,它告知本端TCP:对端已崩溃已重新启动。
  • 对端对保持存活探测分节没有任何响应。TCP将发送另外8个分节,两两像个75秒,试图得到一个响应。
SO_RCVBUF 和 SO_SNDBUF 套接字选项

对于TCP来说,套接字接收缓冲区中可用空间的大小限定了TCP通告对端的窗口大小。TCP套接字接收缓冲区不可能溢出,因为不允许对端发出超过本端所通告的窗口大小的数据,这就是TCP的流量控制。

对于UDP来说,当接受到的数据报装不进套接字缓冲区时,该数据报就被丢弃。

对TCP设置套接字接收缓冲区时函数调用顺序很重要。这是因为TCP的窗口规模选项是在建立连接时用SYN分节与对端互换得到的。
所以对于客户端而言,必须在调用connect之前设置。
对于服务器而言,必须在调用listen之前设置。

SO_RCVTIMEO 和 SO_SNDTIMEO 套接字选项

这2个选项允许我们给套接字的接收和发送设置一个超时值。默认情况下,超时都是禁止的。

struct timeval {
    time_t tv_sec;         // 秒
    suseconds_t tv_usec    // 微妙
}

接收超时影响的5个函数:read,readv,recv,recvfrom和recvmsg。
发送超时影响的5个函数:write,writev,send,sendto 和 sendmsg。

SO_REUSEADDR 和 SO_REUSEPORT 套接字选项

SO_REUSEADDR 和 SO_REUSEPORT 允许启动一个监听服务器绑定一个端口,即使以前建立该端口的连接仍然存在。这个情况通常是:
【1】启动一个监听服务
【2】连接请求到达,派生1个子进程处理
【3】监听服务器终止,但子进程继续外现有连接是上的客户提供服务
【4】重启监听服务器

默认情况下,服务器在4步骤时调用bind时,由于它试图捆绑一个现有连连接(子进程)上的端口,bind调用会失败。但是如果设置了SO_REUSEADDR和SO_REUSEPORT,那么bind将会成功。所有的TCP服务器都应该指定本套接字选项。

  • TIME_WAIT状态有两个存在的理由:
    1. 可靠地实现TCP全双工连接的终止
      如果服务器最后发送的ACK因为某种原因丢失了,那么客户一定会重新发送FIN,这样因为有TIME_WAIT的存在,服务器会重新发送ACK给客户,如果没有TIME_WAIT,那么无论客户有没有收到ACK,服务器都已经关掉连接了,此时客户重新发送FIN,服务器将不会发送ACK,而是RST,从而使客户端报错。也就是说,TIME_WAIT有助于可靠地实现TCP全双工连接的终止。
    2. 允许老的重复分节在网络中消逝
      如果没有TIME_WAIT,我们可以在最后一个ACK还未到达客户的时候,就建立一个新的连接。那么此时,如果客户收到了这个ACK的话,就乱套了,必须保证这个ACK完全死掉之后,才能建立新的连接。也就是说,TIME_WAIT允许老的重复分节在网络中消逝。
SO_RCVLOWAT 和 SO_SNDLOWAT 套接字选项

每个套接字还有一个接收低水位标记和一个发送低水位标记,他们由select函数使用。

接收低水位标记是让select返回"可读"时套接字接收缓冲区中最小的数据量,对于TCP,UDP和SCTP套接字,其默认值为1。

发送低水位标记是让select返回"可写"时套接字发送缓冲区所需要的最小可用空间。对于TCP套接字,默认值通常为2048。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 1、TCP状态linux查看tcp的状态命令:1)、netstat -nat 查看TCP各个状态的数量2)、lso...
    北辰青阅读 9,339评论 0 11
  • NodeJS TCP与UDP 一个最简单的TCP服务端 当一个客户端创建了一个新连接,传递给net.createS...
    77即是正义阅读 6,806评论 0 8
  • 最近在看《UNIX网络编程 卷1》和《FREEBSD操作系统设计与实现》这两本书,我重点关注了TCP协议相关的内容...
    腩啵兔子阅读 1,143评论 0 7
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • 《UNIX 网络编程卷一:套接字联网API》笔记 套接字 套接字编程接口,是在 TCP/IP 协议族中,应用层进入...
    超net阅读 5,745评论 2 13