构造 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() 方法的作用相同

Java 网络编程 —— ServerSocket 详解的更多相关文章

  1. java网络编程(TCP详解)

    网络编程详解-TCP 一,TCP协议的特点              面向连接的协议(有发送端就一定要有接收端)    通过三次连接握手建立连接 通过四次握手断开连接 基于IO流传输数据 传输数据大小 ...

  2. java网络编程(UDP详解)

    UDP详解 一,TCP/IP协议栈中,TCP协议和UDP协议的联系和区别? 联系: TCP和UDP是TCP/IP协议栈中传输层的两个协议,它们使用网络层功能把数据包发送到目的地,从而为应用层提供网络服 ...

  3. java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock

    原文:java并发编程 | 锁详解:AQS,Lock,ReentrantLock,ReentrantReadWriteLock 锁 锁是用来控制多个线程访问共享资源的方式,java中可以使用synch ...

  4. java网络编程serversocket

    转载:http://www.blogjava.net/landon/archive/2013/07/24/401911.html Java网络编程精解笔记3:ServerSocket详解ServerS ...

  5. java并发编程 | 线程详解

    个人网站:https://chenmingyu.top/concurrent-thread/ 进程与线程 进程:操作系统在运行一个程序的时候就会为其创建一个进程(比如一个java程序),进程是资源分配 ...

  6. java网络编程ServerSocket类 和Socket类的常用构造方法及其方法

    Socket类Socket(InetAddress address, int port) 创建一个流套接字并将其连接到指定 IP 地址的指定端口号.Socket(String host, int po ...

  7. Java 多线程编程知识详解

    Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径. 多线程是多任务的一种特别的形式,但多线程使用 ...

  8. Java并发编程--Volatile详解

    摘要      Volatile是Java提供的一种弱同步机制,当一个变量被声明成volatile类型后编译器不会将该变量的操作与其他内存操作进行重排序.在某些场景下使用volatile代替锁可以减少 ...

  9. Java并发编程(详解wait(), notify(),sleep())

    http://blog.csdn.net/luckyzhoustar/article/details/48179161

  10. Java网络编程和NIO详解开篇:Java网络编程基础

    Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...

随机推荐

  1. linux开发基于iMX6ULL-uboot编译环境配置

    1.下载半导体官方的uboot和linux内核固件 2.下载uboot 3.下载linux内核(选择5.4版本的分支下载) 下载后如下所示 解压后如下 查看文件夹中的内容 创建一个git仓库然后开始自 ...

  2. 分享我对DiscuzQ这款现代化开源轻社区的二次开发成果。DiscuzQ依然是站长的最佳选择!

    简要说一下二开的功能:贴文列表样式优化.增加国内 AI 大模型功能.增加社区 AI 助手(会自动发帖和回帖).编辑器功能优化.pc 端导航优化.h5 端导航优化.修复各种加载不出来加载缓慢的问题等等细 ...

  3. 你所不知道的ASP.NET Core进阶系列(三)

    前言 一年多没更新博客,上一次写此系列还是四年前,虽迟但到,没有承诺,主打随性,所以不存在断更,催更,哈哈,上一篇我们细究从请求到绑定详细原理,本篇则是探讨模型绑定细节,当一个问题产生到最终解决时,回 ...

  4. echarts官网文档打开慢的解决方法

    echarts官网文档打开慢的解决方法由于我们在做大数据屏的时候需要很多echarts图表,这个过程中也会遇到需要查询echarts官网文档.手册.配置项的时候,但是由于网站在国外,访问很慢或者打不开 ...

  5. Echarts 柱形图最全详解

    Echarts 是一款基于 JavaScript 的开源可视化图表库,被广泛应用于数据可视化领域.它提供了丰富的图表类型和交互功能,其中柱形图是最常用和重要的一种图表类型之一.下面是对 Echarts ...

  6. 介绍一个我开源的项目:一键部署 VictoriaMetrics 群集

    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 我实在是非常喜欢这个强大的 metrics 监控组件 Vi ...

  7. 七天.NET 8操作SQLite入门到实战 - 第六天后端班级管理相关接口完善和Swagger自定义配置

    前言 在上一章节我们在后端框架中引入 SQLite-net ORM 并封装常用方法(SQLiteHelper),今天我们的任务是设计好班级管理相关的表.完善后端班级管理相关接口并对Swagger自定义 ...

  8. Grafana系列-Loki-基于日志实现告警

    系列文章 Loki 系列文章 前言 实际应用中除了基于 Metrics 告警, 往往还有基于日志的告警需求, 可以作为基于 Metrics 告警之外的一个补充. 典型如基于 NGINX 日志的错误率告 ...

  9. [CF1830D] Mex Tree

    题目描述 You are given a tree with $ n $ nodes. For each node, you either color it in $ 0 $ or $ 1 $ . T ...

  10. [USACO2007NOVS] Milking Time S

    题目描述 Bessie 可以在接下来 \(N\) 个小时内产奶,为了方便,我们把这 \(N\) 个小时 \(0\dots N-1\) 编号. FJ 在这 \(N\) 个小时内有 \(M\) 段时间可以 ...