UNIX网络编程——通用套接字选项
1. SO_BROADCAST 套接字选项
本选项开启或禁止进程发送广播消息的能力。只有数据报套接字支持广播,并且还必须是在支持广播消息的网络上(例如以太网,令牌环网等)。我们不可能在点对点链路上进行广播,也不可能在基于连接的传输协议(例如TCP和SCTP)之上进行广播。
2. SO_DEBUG 套接字选项
本选项仅由TCP支持。当给一个TCP套接字开启本选项时,内核将为TCP在该套接字发送和接受的所有分组保留详细跟踪信息。这些信息保存在内核的某个环形缓冲区中,并可使用trpt程序进行检查。
3. SO_KEEPALIVE 套接字选项
给一个TCP套接字设置保持存活选项后,如果2小时内在该套接字的任何一方向上都没有数据交换,TCP就自动给对端发送一个保持存活探测分节。这是一个对端必须相应的TCP分节,它会导致以下3种情况之一。
(1)对端以期望的ACK响应。应用进程得不到通知(因为一切正常)。在又经过仍无动静的2小时后,TCP将发出另一个探测分节。
(2)对端以RST响应,它告知本端TCP:对端已崩溃且已重新启动。该套接字的待处理错误被置为ECONNRESET,套接字本身则被关闭。
(3)对端对保持存活探测分节没有任何响应。
如果根本没有对TCP的探测分节的响应,该套接字的待处理错误就被置为ETIMEOUT,套接字本身则被关闭。然而如果该套接字收到一个ICMP错误作为某个探测分节的响应,那就返回响应的错误,套接字本身也被关闭。
本选项的功能是检测对端主机是否崩溃或变的不可达(譬如拨号调制解调器连接掉线,电源发生故障等等)。如果对端进程崩溃,它的TCP将跨连接发送一个FIN,这可以通过调用select很容易的检测到。
本选项一般由服务器使用,不过客户也可以使用。服务器使用本选项时因为他们花大部分时间阻塞在等待穿越TCP连接的输入上,也就是说在等待客户的请求。然而如果客户主机连接掉线,电源掉电或者系统崩溃,服务器进程将永远不会知道,并将继续等待永远不会到达的输入。我们称这种情况为半开连接。保持存活选项将检测出这些半开连接并终止他们。
4. SO_LINGER 套接字选项
本选项指定close函数对面向连接的协议(例如TCP和SCTP,但不是UDP)如何操作。默认操作是close立即返回,但是如果有数据残留在套接字发送缓冲区中,系统将试着把这些数据发送给对端。
5. SO_RCVBUF和SO_SNDBUF套接字选项
每个套接字都有一个发送缓冲区和一个接收缓冲区。
接收缓冲区被TCP,UDP和SCTCP用来保存接收到的数据,直到由应用进程读取。对于TCP来说,套接字接收缓冲区可用空间的大小限制了TCP通告对端的窗口大小。TCP套接字接收缓冲区不可以溢出,因为不允许对端发出超过本端所通告窗口大小的数据。这就是TCP的流量控制,如果对端无视窗口大小而发出了超过窗口大小的数据,本端TCP将丢弃它们。然而对于UDP来说,当接收到的数据报装不进套接字接收缓冲区时,该数据报就被丢弃。回顾一下,UDP是没有流量控制的:较快的发送端可以很容易的淹没较慢的接收端,导致接收端的UDP丢弃数据报。
这两个套接字选项允许我们改变着两个缓冲区的默认大小。对于不同的实现,默认值得大小可以有很大的差别。如果主机支持NFS,那么UDP发送缓冲区的大小经常默认为9000字节左右的一个值,而UDP接收缓冲区的大小则经常默认为40000字节左右的一个值。
当设置TCP套接字接收缓冲区的大小时,函数调用的顺序很重要。这是因为TCP的出口规模选项时在建立连接时用SYN分节与对端互换得到的。对于客户,这意味着SO_RCVBUF选项必须在调用connect之前设置;对于服务器,这意味着该选项必须在调用listen之前给监听套接字设置。给已连接套接字设置该选项对于可能存在的出口规模选项没有任何影响,因为accept直到TCP的三路握手玩抽才会创建并返回已连接套接字。这就是必须给监听套接字设置本选项的原因。
6. SO_RCVLOWAT 和 SO_SNDLOWAT套接字选项
每个套接字还有一个接收低水位标记和一个发送低水位标记。他们由select函数使用,这两个套接字选项允许我们修改这两个低水位标记。
接收低水位标记是让select返回“可读”时,套接字接收缓冲区中所需的数据量。对于TCP,UDP和SCTP套接字,其默认值为1。发送低水位标记是让select返回“可写”时套接字发送缓冲区中所需的可用空间。对于TCP套接字,其默认值通常为2048。UDP也使用发送低水位标记,然而由于UDP套接字的发送缓冲区中可用空间的字节数从不改变(意味UDP并不为由应用进程传递给它的数据报保留副本),只要一个UDP套接字的发送缓冲区大小大于该套接字的低水位标记,该UDP套接字就总是可写。我们记得UDP并没有发送缓冲区,而只有发送缓冲区大小这个属性。
7. SO_RCVTIMEO 和 SO_SNDTIMEO套接字选项
这两个选项允许我们给套接字的接收和发送设置一个超时值。注意,访问他们的getsockopt和setsockopt函数的参数是指向timeval结构的指针,与select所用参数相同。这可让我们用秒数和微妙数来规定超时。我们通过设置其值为0s和0μs来禁止超时。默认情况下着两个超时都是禁止的。
接收超时影响5个输入函数:read,readv,recv,recvfrom和recvmsg。发送超时影响5个输出函数:write,writev,send,sendto和sendmsg。
8. SO_REUSEADDR 和 SO_REUSEPORT 套接字选项
SO_REUSEADDR套接字选项能起到以下4个不同的功用。
(1)SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知的端口,即使以前建立的将该端口用作他们的本地端口的连接仍存在。这个条件通常是这样碰到的:
(a)启动一个监听服务器;
(b)连接请求到达,派生一个子进程来处理这个客户;
(c)监听服务器终止,但子进程继续为现有连接上的客户提供服务;
(d)重启监听服务器。
默认情况下,当监听服务器在步骤d通过调用socket,bind和listen重新启动时,由于他试图捆绑一个现有连接(即正由早先派生的那个子进程处理着的连接)上的端口,从而bind调用会失败。但是如果该服务器在socket和bind两个调用之间设置了SO_REUSEADDR套接字选项,那么将成功。所有TCP服务器都应该指定本套接字选项,以允许服务器在这种情况下被重新启动。
(2)SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例,只要每个实例捆绑一个不同的本地IP地址即可。对于TCP,我们绝对不可能启动捆绑相同IP地址和相同端口号的多个服务器:这是完全重复的捆绑,即使我们给第二个服务器设置了SO_REUSEADDR套接字也不管用。
(3)SO_REUSEADDR 允许单个进程捆绑同一端口到多个套接字上,只要每次捆绑指定不同的本地IP地址即可。
(4)SO_REUSEADDR允许完全重复的捆绑:当一个IP地址和端口号已绑定到某个套接字上时,如果传输协议支持,同样的IP地址和端口还可以捆绑到另一个套接字上。一般来说本特性仅支持UDP套接字。
UNIX网络编程——通用套接字选项的更多相关文章
- UNIX网络编程——原始套接字(dos攻击)
原始套接字(SOCK_RAW).应用原始套接字,我们可以编写出由TCP和UDP套接字不能够实现的功能. 注意原始套接字只能够由有 root权限的人创建. 可以参考前面的博客<<UNIX网络 ...
- UNIX网络编程——原始套接字的魔力【续】
如何从链路层直接发送数据帧 上一篇里面提到的是从链路层"收发"数据,该篇是从链路层发送数据帧. 上一节我们主要研究了如何从链路层直接接收数据帧,可以通过bind函数来将原始套接字绑 ...
- UNIX网络编程——原始套接字SOCK_RAW
实际上,我们常用的网络编程都是在应用层的报文的收发操作,也就是大多数程序员接触到的流式套接字(SOCK_STREAM)和数据包式套接字(SOCK_DGRAM).而这些数据包都是由系统提供的协议栈实现, ...
- UNIX网络编程——设置套接字超时
在涉及套接字的I/O操作上设置超时的方法有以下3种: 调用alarm,它在指定超时期时产生SIGALRM信号.这个方法涉及信号处理,而信号处理在不同的实现上存在差异,而且可能干扰进程中现有的alarm ...
- UNIX网络编程——原始套接字的魔力【下】
可以接收链路层MAC帧的原始套接字 前面我们介绍过了通过原始套接字socket(AF_INET, SOCK_RAW, protocol)我们可以直接实现自行构造整个IP报文,然后对其收发.提醒一点,在 ...
- UNIX网络编程——原始套接字的魔力【上】
基于原始套接字编程 在开发面向连接的TCP和面向无连接的UDP程序时,我们所关心的核心问题在于数据收发层面,数据的传输特性由TCP或UDP来保证: 也就是说,对于TCP或UDP的程序开发,焦点在Dat ...
- unix网络编程——TCP套接字编程
TCP客户端和服务端所需的基本套接字.服务器先启动,之后的某个时刻客户端启动并试图连接到服务器.之后客户端向服务器发送请求,服务器处理请求,并给客户端一个响应.该过程一直持续下去,直到客户端关闭,给服 ...
- <unix网络编程>UDP套接字编程
典型的UDP客户/服务器程序的函数调用如下: 1.缓冲区 发送缓冲区用虚线表示,任何UDP套接字都有发送缓冲区,不过该缓冲区仅能表示写到该套接字的UDP数据报的上限.如果应用进程写一个大于套接字缓冲区 ...
- 通用套接字选项和TCP套接字选项
1. 套接字选项函数原型: #include <sys/socket.h> int getsockopt(int sockfd, int level, int optname, void ...
随机推荐
- [bzoj4821][Sdoi2017]相关分析
来自FallDream的博客,未经允许,请勿转载,谢谢. Frank对天文学非常感兴趣,他经常用望远镜看星星,同时记录下它们的信息,比如亮度.颜色等等,进而估算出星星的距离,半径等等.Frank不仅喜 ...
- [坑况]饿了么你是这样的前端——vue+element ui 【this dependency was not found:'element-ui/lib/theme-chalk/index.css'】
element ui 坑况:今日pull代码,潇洒npm run dev ,被告知:this dependency was not found:'element-ui/lib/theme-chalk/ ...
- redis中密码设置
先打开redis-server 再打开redis-cli 在redis-cli对redis进行操作 可以通过编辑redis.conf配置文件来设置密码. 1.重启Redis设置密码: 在配置文件中有个 ...
- samba服务器配置过程
SAMBA服务器配置 yum install samba samba-client samba-swat 改变文件权限及用户 vi /etc/samba/smb.conf d+G全删注释 复制下面代码 ...
- python中的函数(定义、多个返回值、默认参数、参数组)
函数定义 在python中函数的定义以及调用如下代码所示: def test(x): y = x+1 return y result = test(2) print(result) 多个返回值的情况 ...
- popen() 使用举例 (转载)
函数原型: #include "stdio.h" FILE *popen( const char* command, const char* mode ) 参数说明: comman ...
- Linux服务器搭建相关教程链接整理
Linux: Linux 教程 | 菜鸟教程 linux下如何添加一个用户并且让用户获得root权限 - !canfly - 博客园 Git: 在 Linux 下搭建 Git 服务器 - 黄棣-dee ...
- Java 8新特性:新语法方法引用和Lambda表达式及全新的Stream API
新语法 方法引用Method references Lambda语法 Lambda语法在AndroidStudio中报错 Stream API 我正参加2016CSDN博客之星的比赛 希望您能投下宝贵 ...
- MySQL系列教程(三)
mySQL集群(cluster) 这一章,我根本不打算写,因为mySQL 的 官方Cluster方案基本上都是bullshit,尤其是它的官方集群方案,竟然都无人维护了,而且mySQL集群完全可以用眼 ...
- cassandra 3.x官方文档(2)---架构解析
写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...