在API中我门可以看到三种前缀,”IP”.”SO”.”TCP”,也分别有独立的意义,”IP”是用来设置IP类设置的(PS:说这话感觉有点白痴),”SO_”其实是SocketOptions的缩写,当然意思我就不解释了,还有一个”TCP_NODELAY”是针对TCP的设置的,先从最常见的讲起吧。
- TCP_NODELAY:
API说明: 对此连接禁用 Nagle 算法
解读: nagle算法根据创建者John Nagle命名。该算法用于对缓冲区内的一定数量的消息进行自动连接。该处理过程(称为Nagling),通过减少必须发送的封包的数量,提高了网络应用程序系统的效率。具体的算法原理自己可以google一下,这个算法说到了缓冲,其实这对实时性要求高的系统会有一定的影响,如IM和游戏,可能会有与缓冲大小太大导致有明显的停顿。在JAVA里面nagle是默认开启的,如果存在需要实时性需求的话可以关闭该算法降低信息的延时。
SO_TIMEOUT:
API说明:设置阻塞 Socket 操作的超时值: ServerSocket.accept(); SocketInputStream.read(); DatagramSocket.receive(); 选项必须在进入阻塞操作前设置才能生效。
解读:该属性是用于在接收数据或请求的时候设置超时时间,可以起作用的方法都是阻塞操作,当这个属性为0(这也是默认值)的时候,永不超时,但是超时之后并不是说明服务将不可用,而是可以通过编码再次调用接收服务,所以个人建议还是设置一个合理值对程序的稳定性还是有一定帮助的。
SO_SNDBUF:
API说明:设置传出网络 I/O 的平台所使用的基础缓冲区大小的提示。
解读:这个发送缓冲区不要与nagle的缓冲区大小认为是同一个东西,其实nagle的最大缓冲区是有MTU来决定的。其实这个属性在windows平台下是设置了内核缓冲区的大小,linux下我还不知道。在win平台上该值默认为8K,这个值设置过小的话会导致数据包发送非常频繁,原因么可以参考一下这篇文章 (很早以前看到的一篇文章,都不知道原文地址了)
SO_REUSEADDR
API说明:设置套接字的 SO_REUSEADDR。在 java 中,它仅用于 MulticastSocket,默认情况下为 MulticastSocket 设置此选项。
解读:其实就是端口重用,为什么要使用这个属性是因为操作系统在关闭连接的时候端口并不是马上释放掉,因为可能还有一些数据没有接受完成,所以再下一次再绑定该端口的时候会导致失败,它的使用场景主要就是在服务器程序关闭后马上启动一个新的服务的时候,这个时候需要设置该属性,否则很大几率会导致绑定端口失败。
SO_RCVBUF
API说明:设置传入网络 I/O 的平台所使用基础缓冲区的大小的提示。
解读:这个接受缓冲区和SO_SNDBUF相反,当大传输量的时候则需要大一点的缓冲区这样可以提高传输速度,但是对应信息量非常小的则可以使用小一点的缓冲区确保数据的及时处理。
SO_OOBINLINE
API说明: 设置 OOBINLINE 选项时,在套接字上接收的所有 TCP 紧急数据都将通过套接字输入流接收。
解读:无。暂时没有用到需要使用的情况,也没有使用案例,所以暂时不做解读。
SO_LINGER
API说明:指定关闭时逗留的超时值。
解读:由于在调用了close()方法之后,程序默认会检查是否还有数据没有接受或者发送完,有的话是需要将这些数据处理完再关闭释放端口。但是人的忍耐是有限度的,不能守夜的大叔要关门了你们还在他妈的加班,所以必须有超时时间,到了时间就强制都赶出门。
SO_KEEPALIVE
API说明:为 TCP 套接字设置 keepalive 选项时,如果在 2 个小时(注:实际值与实现有关)内在任意方向上都没有跨越套接字交换数据,则 TCP 会自动将 keepalive 探头发送到同位体。
解读:在两个小时之内主从双方都没有数据交换的时候,那么TCP会自己发送一个keeplive的探针看对方的状态,返回的状态有三种:1.对方有回应并返回期望的ACK,正常;2.对方有回应但是返回一个RST响应(不清楚的可以查一下RST攻击),不正常,主动关闭连接。3.对方没有响应,说明主机可能都已经关闭,自然也主动断开连接。
SO_BROADCAST
API说明: 为套接字设置 SO_BROADCAST。
解读:用于开启或关闭广播地址上组播功能,当然这个也要在网络环境支持。
SO_BINDADDR
API说明:获取绑定套接字的本地地址(不能仅将此选项“设置”为“得到”,因为套接字是在创建时绑定的,所以本地绑定的地址不可更改)。
解读:这个值是只读的,虽然有set方法支持,但是并不能设置值的,因为绑定的地址在服务器启动的时候就已经定了,是不能改变的,所以这只是一个只读方法。
IP_TOS
API说明:此選項為 TCP 或 UDP Socket在 IP 位址頭中設置服務型別或串流量類別欄位。
解读:这个其实是IP协议中的类型定义标志位,google了一下也没发现有用的答案,参考了rfc791发现其实这个实际上是8个字节的组合,具体的每一位的含义可以参rfc791里面介绍的,其实就是标识这个IP包的数据处理的优先级的标志位(至少我看下来是这种理解),具体使用的时候还是参考协议更准确。
IP_MULTICAST_LOOP
API说明:此选项启用或禁用多播数据报的本地回送。
解读:其实API说得很清楚很了,这里的回送应该127.0.0.1吧(没找到依据,但应该就是这个)
IP_MULTICAST_IF,IP_MULTICAST_IF2
API说明:设置用于发送多播包的传出接口。
解读:这个主要是在机器上有多个网络接口(应该是网卡驱动)中选择需要网卡发送多播包。其实这个只需要用bind方法指定IP就可以做到了。