【Java 网络编程】客户端 Socket 配置 ( 超时时间 | 端口复用 | Nagle 算法 | 心跳包机制 | 连接关闭机制 | 缓冲区大小 | 性能权重设置 | 紧急数据设置 )

简介: 【Java 网络编程】客户端 Socket 配置 ( 超时时间 | 端口复用 | Nagle 算法 | 心跳包机制 | 连接关闭机制 | 缓冲区大小 | 性能权重设置 | 紧急数据设置 )

文章目录

I 设置读取超时时间

II Socket 复用绑定端口设置

III 开启 Nagle 算法 ( 沾包 )

IV 心跳包机制

V 连接关闭处理

VI Socket 紧急数据内敛设置

VII Socket 设置缓冲区大小

VIII Socket 连接性能参数设置



I 设置读取超时时间


1. 设置 Socket 超时时间 , 该超时时间没有实际的概念 , 用于设置与阻塞相关操作的超时时间 , TCP 连接中有两个需要阻塞的操作 :


① 连接服务器操作 ;

② 等待读取服务器发送给客户端的数据 ;

连接超时时间可以单独设置 , 这里设置的读取超时时间 ;


2. 单位 : 毫秒 ( ms ) ;


3. 设置一个非 0 的超时时间 , 当与 Socket 对象关联的 InputStream 输入流执行 read() 操作时 , 其阻塞时间为这个超时时间 , 如果超过了该时间还没有收到任何数据 , 就会抛出异常 ;


socket.setSoTimeout(3000);



II Socket 复用绑定端口设置


设置是否可以复用 Socket 绑定的地址和端口号 : setReuseAddress( true ) ;


socket.setReuseAddress(true);


Socket 连接在建立时 , 会使用之前绑定本地的 IP 地址和端口号 , 这个端口号在使用之后 , 2 分钟之内不允许再次使用 ; 进行了该设置之后 , 可以在连接关闭之后 , 马上使用该本地 IP 地址和端口号 ;




III 开启 Nagle 算法 ( 沾包 )


1. 前提 : TCP 发送数据后 , 接收方会反馈已经接受到的数据 ;


2. 示例 : 客户端如果向服务器端发送 1 字节数据 , 服务器端需要反馈 ACK 信息 , ACK 的命令其大小要比传输的数据还要大 , 其消耗要高于实际的数据传输消耗 ;


3. Nagle 算法引入 : 为了避免上述情况的消耗 , 便有了 Nagle 算法 ;


① 服务器端处理 : 其原理是接收端接到数据后 , 如果数据很小 , 那就多接收几个数据 , 然后将反馈信息一起回送给发送端 ;

② 客户端处理 : 对应的客户端处理便是一条数据发送之后 , 会等待服务器端反馈 , 然后这段时间内如果又有新的数据要发送 , 那么就会将这些数据缓存起来 , 等待前面的数据反馈信息回送之后 , 将发送端缓存的这些数据全部发送出去 ; 这样就出现了沾包的情况 ;

4. Nagle 算法好处 : Nagle 算法有效的减少了因发送少量数据 , 而产生大量的 ACK 回送包的数据量 ; 优化网络带宽 ;


在需要低延迟传输的情况下是需要关闭该算法的 , 该算法会导致数据沾包情况出现 ;


socket.setTcpNoDelay(true);




IV 心跳包机制


设置了 setKeepAlive(true) 之后的效果 : 如果 TCP 连接在 2 小时之内没有数据传输 , 客户端就会发送心跳包 , 服务器端会会送消息 , 如果客户端没有收到服务器端反馈信息 , 就认为该 TCP 连接已经断开 , 客户端会抛出异常信息 ;


//在长时间 ( 2 小时 ) 没有数据交互 , 是否需要发送心跳包确认连接
socket.setKeepAlive(true);



V 连接关闭处理


1. 连接关闭处理 : 对于连接关闭行为处理方式设置 , 调用 setSoLinger 函数设置 ;


2. 关闭情况说明 : 当 Socket 对象调用 close 方法关闭连接时 , 有可能缓冲区中还有数据没有发送完成 , 这个方法就是用于处理这部分缓冲区数据的 ;


3. setSoLinger 函数原型 :


 

/**
     * Enable/disable {@link SocketOptions#SO_LINGER SO_LINGER} with the
     * specified linger time in seconds. The maximum timeout value is platform
     * specific.
     *
     * The setting only affects socket close.
     *
     * @param on     whether or not to linger on.
     * @param linger how long to linger for, if on is true.
     * @exception SocketException if there is an error
     * in the underlying protocol, such as a TCP error.
     * @exception IllegalArgumentException if the linger value is negative.
     * @since 1.1
     * @see #getSoLinger()
     */
    public void setSoLinger(boolean on, int linger) throws SocketException


4. setSoLinger 参数解析 :


① boolean on : TCP 连接关闭处理功能是否打开 , 默认是关闭的 ( false ) ;

② int linger : Socket 调用 close 方法后 , 需要阻塞等待缓冲区数据发送的时间 , 单位毫秒 ;

5. 默认状态 : 如果 boolean on 设置成false , 不处理连接的缓存数据 , 调用 close 会立刻关闭连接 , 系统底层会操作输出流发送剩余缓存数据 , 将缓冲区中的数据发送给连接对方 ; 如果设置 false 不会产生阻塞操作 ;


6. 开启连接关闭处理 : setSoLinger( true , 20 ) 情况 , 如果设置 boolean on 参数为 true , int linger 参数设置一个大于等于 0 的参数 , 那么在关闭的时候 , 阻塞 linger 毫秒 , 之后缓冲区如果还有数据 , 就会被丢弃 , 直接向连接对方发送结束命令 , 无需经过超时等待 ;


超时等待是数据达到对方并返回的最长等待时间 ( MSL ) ;


7. 开启连接关闭处理 ( 不阻塞 ) : setSoLinger( true , 0 ) 情况 , 如果设置成 0 , 那么其后果是不阻塞 , 也不让系统接管输出流 , 立刻丢弃缓冲区数据 , 向对方发送 RST 命令 ;




VI Socket 紧急数据内敛设置


//设置紧急数据是否内敛 , 默认情况时 false 关闭的 ; 
socket.setOOBInline(true);


1. 紧急数据 : 紧急数据是 Socket 对象通过调用 sendUrgentData 发送出去的数据 ; 该方法参数是一个 int 值 , 仅有最低的 8 位是有效的 ;


2. 紧急数据透明特性 : 紧急数据默认情况下与上层的数据是隔离的 , 如客户端给服务器端发送了一条紧急数据 , 服务器端照常接收处理普通数据 , 其不影响数据的接收与处理 , 也不知道客户端发送了紧急数据 ;


3. 接收紧急数据 : 如果服务器端想要接收客户端发送的紧急数据 , 那么需要在获取 Socket 输入流之前设置 socket.setOOBInline(true) , 才能在接收数据时 , 读取到紧急数据 ;


4. 设置紧急数据 : setOOBInline 方法设置紧急数据是否内敛 , 默认情况时 false 关闭的 ;


5. 适用场景 : 使用紧急数据当做心跳包 ;


不建议设置紧急数据内敛 , 可能会影响实际数据的正确性 ;




VII Socket 设置缓冲区大小


1. 缓冲区大小设置包括两个缓冲区设置 :


① 发送缓冲区设置 :

socket.setSendBufferSize(64 * 1024 * 1024);


② 接收缓冲区设置 ;

socket.setReceiveBufferSize(64 * 1024 * 1024);


2. 缓冲区作用 : 缓冲区大小默认 32 KB , 缓冲区大小不是要等到有 32 KB 数据才进行发送和接收 , 而是如果发送和接收的数据大于 32 KB , 如 33 KB , 就会将数据拆分成两包 , 32 KB 和 1KB , 然后进行发送和接收操作 ;


注意设置一定要在连接之前设置 , 连接后设置时无效的 ;




VIII Socket 连接性能参数设置


1. 调用 Socket 对象的 setPerformancePreferences 方法 , 设置连接的性能参数 ; 连接有以下三个性能参数 :


① 连接时间 ;

② 往返延迟 ;

③ 带宽 ;

2. 设置的是权重不是具体性能参数 : 设置的值不是具体的参数 , 而是连接的性能权重 , 对哪个性能要求比较高 ;


3. 连接时间 : 如果该 Socket 的连接很频繁 , 连接后传一个数据 , 马上断开 , 这时候比较看重连接时间性能 , 此时可以将第一个参数设置成 10 , 后两个参数设置成 1 , 表示注重连接时间性能 ;


//设置 连接时间 性能参数较重要
socket.setPerformancePreferences(10, 1, 1);


4. 往返延迟 : 如果开发的是网游服务器 , 此时对延迟很看重 , 这时候可以将第二个参数设置成比较高的权重 ;


//设置 往返延迟 性能参数较重要
socket.setPerformancePreferences(1, 10, 1);


5. 带宽 : 如果开发的是音视频服务器 , 注重带宽性能 , 此时需要将第三个参数设置成较高的权重 ;


//设置 带宽 性能参数较重要
socket.setPerformancePreferences(1, 10, 1);


6. 上面的延迟和带宽的性能是互斥的 , 延迟低 , 就意味着很小的包就要发送一次 , 其带宽就低了 , 延迟高了 , 每次积累很多数据才发送 , 其带宽就相应的提高了 ;


7. 函数原型 :


 

/**
     * Sets performance preferences for this socket.
     *
     * <p> Sockets use the TCP/IP protocol by default.  Some implementations
     * may offer alternative protocols which have different performance
     * characteristics than TCP/IP.  This method allows the application to
     * express its own preferences as to how these tradeoffs should be made
     * when the implementation chooses from the available protocols.
     *
     * <p> Performance preferences are described by three integers
     * whose values indicate the relative importance of short connection time,
     * low latency, and high bandwidth.  The absolute values of the integers
     * are irrelevant; in order to choose a protocol the values are simply
     * compared, with larger values indicating stronger preferences. Negative
     * values represent a lower priority than positive values. If the
     * application prefers short connection time over both low latency and high
     * bandwidth, for example, then it could invoke this method with the values
     * {@code (1, 0, 0)}.  If the application prefers high bandwidth above low
     * latency, and low latency above short connection time, then it could
     * invoke this method with the values {@code (0, 1, 2)}.
     *
     * <p> Invoking this method after this socket has been connected
     * will have no effect.
     *
     * @param  connectionTime
     *         An {@code int} expressing the relative importance of a short
     *         connection time
     *
     * @param  latency
     *         An {@code int} expressing the relative importance of low
     *         latency
     *
     * @param  bandwidth
     *         An {@code int} expressing the relative importance of high
     *         bandwidth
     *
     * @since 1.5
     */
    public void setPerformancePreferences(int connectionTime,
                                          int latency,
                                          int bandwidth)


目录
相关文章
|
11月前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
256 11
|
3月前
|
JSON 移动开发 网络协议
Java网络编程:Socket通信与HTTP客户端
本文全面讲解Java网络编程,涵盖TCP与UDP协议区别、Socket编程、HTTP客户端开发及实战案例,助你掌握实时通信、文件传输、聊天应用等场景,附性能优化与面试高频问题解析。
|
1月前
|
JSON 网络协议 安全
【Java】(10)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
136 1
|
1月前
|
JSON 网络协议 安全
【Java基础】(1)进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化
几乎所有的操作系统都支持进程的概念,进程是处于运行过程中的程序,并且具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位一般而言,进程包含如下三个特征。独立性动态性并发性。
157 1
|
1月前
|
机器学习/深度学习 分布式计算 Java
Java与图神经网络:构建企业级知识图谱与智能推理系统
图神经网络(GNN)作为处理非欧几里得数据的前沿技术,正成为企业知识管理和智能推理的核心引擎。本文深入探讨如何在Java生态中构建基于GNN的知识图谱系统,涵盖从图数据建模、GNN模型集成、分布式图计算到实时推理的全流程。通过具体的代码实现和架构设计,展示如何将先进的图神经网络技术融入传统Java企业应用,为构建下一代智能决策系统提供完整解决方案。
281 0
|
Java 程序员
JAVA程序员的进阶之路:掌握URL与URLConnection,轻松玩转网络资源!
在Java编程中,网络资源的获取与处理至关重要。本文介绍了如何使用URL与URLConnection高效、准确地获取网络资源。首先,通过`java.net.URL`类定位网络资源;其次,利用`URLConnection`类实现资源的读取与写入。文章还提供了最佳实践,包括异常处理、连接池、超时设置和请求头与响应头的合理配置,帮助Java程序员提升技能,应对复杂网络编程场景。
252 9
|
人工智能 Java 物联网
JAVA网络编程的未来:URL与URLConnection的无限可能,你准备好了吗?
随着技术的发展和互联网的普及,JAVA网络编程迎来新的机遇。本文通过案例分析,探讨URL与URLConnection在智能API调用和实时数据流处理中的关键作用,展望其未来趋势和潜力。
171 7
|
8月前
|
存储 网络协议 安全
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
344 23
|
9月前
|
安全 网络协议 Java
Java网络编程封装
Java网络编程封装原理旨在隐藏底层通信细节,提供简洁、安全的高层接口。通过简化开发、提高安全性和增强可维护性,封装使开发者能更高效地进行网络应用开发。常见的封装层次包括套接字层(如Socket和ServerSocket类),以及更高层次的HTTP请求封装(如RestTemplate)。示例代码展示了如何使用RestTemplate简化HTTP请求的发送与处理,确保代码清晰易维护。

热门文章

最新文章