Java 网络编程 —— ServerSocket 详解

构造 ServerSocket

ServerSocket 的构造方法有以下几种重载形式

ServerSocket() throws IOException
ServerSocket(int port) throws IOException
ServerSocket(int port, int backlog) throws IOException
ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException

参数 port 指定服务器要绑定的端口(即服务器要监听的端口),参数 backlog 指定客户连接请求队列的长度,参数 bindAddr 指定服务器要绑定的 IP 地址

1. 绑定端口

除了第 1 个不带参数的构造方法,其他构造方法都会使服务器与特定端口绑定,由参数 port 指定,无法绑定则抛出 IOException,一般是因为端口已经被其他服务占用,或者没有足够的权限去绑定

如果把参数 port 设为 0,则表示由操作系统为服务器分配一个任意的可用端口,也被称为匿名端口。对于多数服务器,会使用明确的端口,而不会使用匿名端口,因为客户程序需要事先知道服务器的端口,才能方便地访问服务器

ServerSocket(int port) throws IOException

2. 设定客户连接请求队列的长度

当服务器进程运行时,可能会同时监听到多个客户的连接请求,管理客户连接请求的任务是由操作系统来完成的。操作系统把这些连接请求存储在一个先进先出的队列中,许多操作系统都限定了队列的最大长度,一般为 50。当队列中的连接请求达到了队列的最大长度时,服务器进程所在的主机会拒绝新的连接请求,只有当服务器进程通过 ServerSocket 的 accept() 方法从队列中取出连接请求,使队列腾出空位,队列才能继续加入新的连接请求

ServerSocket 构造方法的 backlog 参数用来显式设置连接请求队列的长度,它将覆盖操作系统限定的队列的最大长度。值得注意的是,在以下几种情况中,仍然会采用操作系统限定的队列的最大长度:

  • backlog 参数的值大于操作系统限定的队列的最大长度
  • backlog 参数的值小于或等于 0
  • 在 ServerSocket 构造方法中没有设置 backlog 参数

3. 设定绑定的 IP 地址

ServerSocket 的第 4 个构造方法有个 bindAddr 参数,它显式地指定服务器要绑定的 IP 地址,适用于具有多个 IP 地址的主机

接收和关闭与客户的连接

ServerSocket 的 accept() 方法从连接请求队列中取出一个客户的连接请求,然后创建与客户连接的 Socket 对象,井将它返回。如果队列中没有连接请求,accept() 方法就会一直等待下去。接下来,服务器从 Socket 对象获得输入流和输出流,就能与客户交换数据了

以下代码展示了单线程服务器采用的通信流程

public void service() {
	while (true) {
        Socket socket = null;
        try {
            // 从连接请求队列中取出一个连接
            socket = serverSocket.accept();
            System.out.printin("New connection accepted " + socket,getInetAddress() + ":" + socket.getPort());
            //接收和发送数据
            ...
        } catch (IOException e) {
            // 这只是与单个客户通信时遇到的异常,可能是由于客户端过早断开连接引起的
            // 这种异常不应该中断整个while循环
            e.printStackTrace();
        } finally {
            try {
                // 与一个客户通信结束后,要关闭Socket
                if(socket != null) socket.close();
            }catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

关闭 ServerSocket

ServerSocket 的 close() 方法使服务器释放占用的端口,并且断开与所有客户的连接

ServerSocket 的 isClosed() 方法判断 ServerSocket 是否关闭,只有执行了 ServerSocket 的 close() 方法,isClosed() 方法才返回 true,否则即使 ServerSocket 还有没有和特定端口绑定,该方法也会返回 false

ServerSocker 的 isBound() 方法判断 ServerSocket 是否已经与一个端口绑定,只要 ServerSocket 已经与一个端口绑定,即使它已经被关闭,该方法也会返回 true

如果需要判断一个 ServerSocket 是否已经与特定端口绑定,并且还没有被关闭,则可以采用以下方式

boolean isOpen = serverSocket.isBound() && !serverSocket.isClosed();

获取 ServerSocket 的信息

ServerSocket 的以下两个 get 方法分别用于获得服务器绑定的 IP 地址,以及绑定的端口

public InetAddress getInetAddress()
publlc int getLocalPort()

ServerSocket 选项

1. SO_TIMEOUT

表示 ServerSocket 的 accept() 方法等待客户连接的超时时间,以 ms 为单位。如果 SO_TIMEOUT 的值为 0 则表示永远不会超时,这是 SO_TIMEOUT 的默认值

public void setSoTimeout(int timeout) throws SocketException
public int getSoTimeout() throws IOException

2. SO_REUSEADDR

这个选项与 Socket 的 SO_REUSEADDR 选项相同,决定如果网络上仍然有数据向旧的 ServerSocket 传输,那么是否允许新的 ServerSocket 绑定到与旧的 ServerSocket 同样的端口

public void setResuseAddress(boolean on) throws SocketException
public boolean getResuseAddress() throws SocketException

3. SO_RCVBUF

表示服务器端的用于接收数据的缓冲区的大小,以字节为单位

public void setReceiveBufferSize(int size) throws SocketException
public int getReceiveBufferSize() throws SocketException

4. 设定连接时间、延迟和带宽的相对重要性

该方法的作用与 Socket 的 setPerformancePreferences() 方法的作用相同

原文链接:https://www.cnblogs.com/Yee-Q/p/17367727.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 网络编程 —— ServerSocket 详解 - Python技术站

(0)
上一篇 2023年5月1日
下一篇 2023年5月2日

相关文章

  • Jsp+Servlet实现文件上传下载 删除上传文件(三)

    这篇攻略是介绍如何使用 JSP 和 Servlet 来实现文件上传下载以及删除上传文件。其中包含以下内容: 上传文件处理(上传文件存储,上传文件名称处理) 下载文件处理(下载文件存储) 删除文件处理 除此之外,还会用到一些库和工具,如 commons-fileupload、commons-io、bootstrap。 上传文件处理 上传文件存储 在上传文件之前…

    Java 2023年6月15日
    00
  • springboot做代理分发服务+代理鉴权的实现过程

    下面我为您详细讲解“springboot做代理分发服务+代理鉴权的实现过程”的完整攻略。 什么是代理分发服务? 代理分发服务就是将客户端请求代理到后端的具体服务,以实现负载均衡、服务的高可用等目的。Spring Boot是一个非常适合构建代理分发服务的框架。 代理分发服务的实现方式 代理分发服务的实现方式主要有两种,一种是自己实现代理分发的逻辑,另一种是使用…

    Java 2023年5月20日
    00
  • JSP 不能解析EL表达式的解决办法

    JSP 是一种在 Java Web 应用程序中广泛使用的技术,它可以将文本、HTML、XML 和 Java 代码混合在同一个文件中。EL 表达式是 JSP 技术中一个重要的特性,它允许在 JSP 页面上轻松访问和操作 Java 对象。但是,在一些情况下,JSP 无法正确解析 EL 表达式,这会导致页面无法正确渲染。接下来,我们将介绍一些解决 JSP 无法解析…

    Java 2023年6月15日
    00
  • WIN10环境 Maven的安装与配置详细教程

    下面是WIN10环境 Maven的安装与配置详细教程的完整攻略: 概述 Maven是一个基于Java的自动化构建工具,用于管理Java项目的构建、文档生成和依赖管理等。在WIN10环境下,需要完成Maven的安装和配置。 步骤 1. 下载和安装JDK 在使用Maven之前,需要先安装JDK(Java Development Kit)。建议下载Oracle J…

    Java 2023年5月19日
    00
  • Spring security基于数据库中账户密码认证

    Spring Security是Spring框架中提供的一个安全权限框架。它将认证(Authentication)和授权(Authorization)抽象为一个独立的模块,可以快速地将安全性集成到应用程序中。Spring Security可以基于多种认证方式,包括基于数据库中账户密码的认证。 基于数据库中账户密码认证的Spring Security攻略如下:…

    Java 2023年5月20日
    00
  • SpringBoot整合Redis实现序列化存储Java对象的操作方法

    下面我来详细讲解“SpringBoot整合Redis实现序列化存储Java对象的操作方法”的完整攻略。 一、准备工作 在使用SpringBoot整合Redis以实现Java对象的存储前,我们需要先进行一些准备工作。 在pom.xml中引入Redis相关的依赖,可以使用Jedis或Lettuce两个库。这里我以Lettuce为例: <dependency…

    Java 2023年6月3日
    00
  • SpringBoot定时任务实现数据同步的方法

    这里是关于“Spring Boot定时任务实现数据同步的方法”的完整攻略。 1. 在Spring Boot中使用定时任务 在Spring Boot中,我们可以通过使用@EnableScheduling注解来开启定时任务的支持。注解需要在Spring Boot的应用主类上添加。添加之后,我们就可以使用Spring的@Scheduled注解来定义我们的定时任务了…

    Java 2023年5月20日
    00
  • 常见的Java异步编程模型有哪些?

    常见的Java异步编程模型有以下几种: 回调函数(Callback)模式:将一个方法作为参数传递给其他方法,在调用方法完成后再调用该方法。 Future模式:以FutureResult对象的形式返回一个异步操作的结果,并在需要的时候通过FutureResult.get()方法获取该结果。 观察者(Observer)模式:观察者模式是一种基于事件的异步通信机制…

    Java 2023年5月11日
    00
合作推广
合作推广
分享本页
返回顶部