Java 网络编程 —— ServerSocket 详解

news/2024/11/24 2:15:00/

构造 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 {// 与一个客户通信结束后,要关闭Socketif(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() 方法的作用相同



http://www.ppmy.cn/news/59553.html

相关文章

数据发送流程

在发送模式下,UART 的串行数据发送电路主要包括一个发送移位寄存器(TSR),TSR 功能是将数据 逐个移位送出。待发数据必须先写到发送缓冲区中。 TXIFx 是发送中断标志位,可配置为发送缓冲区空或TSR 空。 数据的发送支持7bit 、8bit 或9bit 数据…

HTML(四) -- 多媒体设计

目录 1. 视频标签 2. 音频标签 3. 资源标签(定义媒介资源 ) 1. 视频标签 属性值描述autoplayautoplay如果出现该属性,则视频在就绪后马上播放。controlscontrols表示添加标准的视频控制界面,包括播放、暂停、快进、音量等…

缓存击穿,穿透,雪崩

一、缓存穿透 是用户访问的数据既不在缓存当中,也不在数据库中。 如果从数据库查询不到数据,则不写入缓存。这就导致每次请求都会到数据库进行查询,缓存也失去了意义。 当高并发或有人利用不存在的Key频繁攻击时,数据库的压力骤…

【Go语言Web开发】Todolist 项目重构

写在前面 这篇文章我们来重构一下之前写的Todolist项目,包括项目结构,代码逻辑 项目地址:https://github.com/CocaineCong/TodoList 1. 项目结构的改变 1.1 改变前的项目架构 TodoList/ ├── api ├── cache ├── conf ├── middle…

python文件操作的基本流程

引入 程序运行过程中产生的数据会保存到内存中,如果想要永久保存下来,就必须将数据存放在硬盘上,应用程序如果想要操作计算机的硬件就必须通过操作系统,文件就是操作系统提供给应用程序来操作硬盘的虚拟概念,应用程序…

Windows 10 字体模糊发虚的问题及解决方法

Windows 10字体模糊发虚! 如何解决?Windows 10是一款常见的操作系统,它拥有各种各样的功能,但是有些用户发现,在使用Windows 10时,字体会变得模糊发虚,这给用户带来了很多不便。下面,我们就来看看如何解决…

【python基础语法十】面向对象

面向对象的程序开发 """ 用几大特征表达一类事物称为一个类,类更像是一张图纸,表达的是一个抽象概念 对象是类的具体实现,更像是由这图纸产出的具体物品,类只有一个,但对象可以通过这个类实例化出多个 对象是类的实例,类是对象的模板 *类中的成员只有方法和属性…

单链表——单链表的定义及基本操作(初始化、头插法尾插法建表、查找、插入、删除、判空等)

单链表的定义 由于顺序表存在以下缺陷,所以衍生出了链表,而链表种类有很多种,今天我们讲的是单链表。 顺序表存在的问题如下 1.中间/头部的插入删除,时间复杂度为O(N) 2. 增容需要申请新空间,拷贝数据,释…