钿稳铆 发表于 2026-1-27 04:00:03

1、ServerSocket简单介绍

  ServerSocket.class实现了服务器套接字的功能。服务器套接字会等待通过网络传来的请求。它会根据该请求执行一些操作,然后可能向请求者返回结果。ServerSocket.class的UML关系图如下所示:
https://img2024.cnblogs.com/blog/2485827/202601/2485827-20260126105043372-887991768.png
一、构造函数

ServerSocket的构造函数有以下几种重载形式:
public ServerSocket() throws IOException;public ServerSocket(int port) throws IOException;public ServerSocket(int port, int backlog) throws IOException;public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException;ServerSocket(SocketImpl impl);1、int port指定服务器要绑定的端口(即服务器要监听的端口),如果运行时无法绑定1~65536之间的某个端口号,会抛出BindException(它是IOException的子类),如下所示:
https://img2024.cnblogs.com/blog/2485827/202601/2485827-20260126105139361-1931405846.png
BindException一般是由以下2种原因造成的:
①、端口已经被其他服务器进程占用。
②、在某些操作系统中,如果没有以超级用户的身份来运行服务器程序,那么操作系统不允许服务器绑定到1~1023之间的端口。
2、int backlog指定客户连接请求队列的长度,如果没有指定,默认值是50;
3、InetAddress bindAddr指定服务器要绑定的IP地址;
二、客户连接请求队列的长度

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

[*]Server端
package com.xxx.serverSocket;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Server {   private ServerSocket serverSocket = null;   public Server() throws IOException {      this.serverSocket = new ServerSocket(8080,3);//端口号为8080,请求连接的最大长度为3      System.out.println("服务器启动");   }   public void service() {      while (true) {         Socket socket = null;         try {            socket = serverSocket.accept();            System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort());         } catch (IOException e) {            e.printStackTrace();         } finally {            if (socket != null) {               try {                  socket.close();//无论如何,最终都会关闭这个Socket               } catch (IOException e) {                  e.printStackTrace();               }            }         }      }   }   public static void main(String[] args) throws Exception {      Server server = new Server();      Thread.sleep(600 * 1000);//    server.service();   }}Server端运行结果如下:
https://img2024.cnblogs.com/blog/2485827/202601/2485827-20260126105557093-1857568249.png

[*]Cient端
package com.xxx.serverSocket;import java.net.Socket;public class Client {   public static void main(String[] args) throws Exception {      Socket[] sockets = new Socket;      for (int i = 0; i < sockets.length; i++) {         sockets = new Socket("127.0.0.1", 8080);         System.out.println("第" + (i + 1) + "次连接成功");      }      Thread.sleep(3000);      for (int i = 0; i < sockets.length; i++) {         sockets.close();      }   }}Cient端运行结果如下:
https://img2024.cnblogs.com/blog/2485827/202601/2485827-20260126105632614-2121452734.png
如果将Server端的代码修改如下(只修改了main函数中的内容,调用service()函数来处理Client端的连接Socket,并且在finally块中关闭Client端的连接Socket):
package com.xxx.serverSocket;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;public class Server {   private ServerSocket serverSocket = null;   public Server() throws IOException {      this.serverSocket = new ServerSocket(8080,3);//请求连接的最大长度为3      System.out.println("服务器启动");   }   public void service() {      while (true) {         Socket socket = null;         try {            socket = serverSocket.accept();            System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort());         } catch (IOException e) {            e.printStackTrace();         } finally {            if (socket != null) {               try {                  socket.close();               } catch (IOException e) {                  e.printStackTrace();               }            }         }      }   }   public static void main(String[] args) throws Exception {      Server server = new Server();      server.service();   }}Server端运行结果如下:
https://img2024.cnblogs.com/blog/2485827/202601/2485827-20260126110750626-549626388.png
Cient端运行结果如下:
https://img2024.cnblogs.com/blog/2485827/202601/2485827-20260126110818848-1170985684.png
三、构造函数绑定IP和bind()函数绑定port

3.1、构造函数绑定IP

  如果主机只有一个IP地址,那么在默认情况下,服务器程序就与该IP地址绑定。下面这个构造函数就是绑定IP、port、和连接队列长度的构造函数:
public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException;InetAddress bindAddr用来指定IP地址。该构造方法适用于具有多个IP地址的主机。假定一个主机有两个网卡,一个网卡用于连接到Internet,IP地址为222.67.5.94,另一个网卡用于连接到本地局域网,IP地址为192.168.3.4。如果服务器仅仅被本地局域网中的客户访问,那么可以按如下方式创建
ServerSocket serverSocket = new ServerSocket(8080,3,InetAddress.getByName("192.168.3.4"));3.2、bind()函数绑定port

  ServerSocket有一个不带参数的默认构造方法。通过该方法创建的ServerSocket不与任何端口绑定,需要通过bind()函数,如下所示:
ServerSocket serverSocket = new ServerSocket();//需要先把SO_REUSEADDR选项设为true(SO_REUSEADDR在setReuseAddress()函数的源码里),才能进行port绑定serverSocket.setReuseAddress(true);serverSocket.bind(new InetSocketAddress(8000));//与8000端日进行绑定如果把以上程序代码改为如下所示,则会失效(因为SO_REUSEADDR选项必须在服务器绑定端口之前设置才有效):
ServerSocket serverSocket = new ServerSocket(8000);serverSocket.setReuseAddress(true);四、close()函数、isBound()函数、isClosed()函数

  ServerSocket的close()函数使服务器释放占用的端口,并且断开与所有客户的连接。当一个服务器程序运行结束时,即使没有执行ServerSocket的close()函数,操作系统也会释放这个服务器占用的端口。因此,服务器程序并不一定要在结束之前执行ServerSocket的close()函数。
在某些情况下,如果希望及时释放服务器的端口,以便让其他程序能占用该端口,则可以显式地调用ServerSocket的close()方法。例如以下代码用于扫描1~65535之间的端口号。如果ServerSocket成功创建,则意味着该端口未被其他服务器进程绑定,否则说明该端口已经被其他进程占用,如下代码所示(个人认为这种方式不好,不如执行shell命令再解析shell命令返回的字符串高效,windows系统查看端口号的shell命令为netstat -ano):
https://img2024.cnblogs.com/blog/2485827/202601/2485827-20260126111400473-384683648.png
  ServerSocket的isBound()函数判断ServerSocket是否已经与一个端口绑定,只要ServerSocket已经与一个端口绑定,即使它已经被关闭,isBound()函数也会返回true。
  如果需要判断一个ServerSocket是否已经与特定端口绑定,并且还没有被关闭,则可以采用以下方式:
boolean isOpen = serverSocket.isBound() && !serverSocket.isClosed();五、getInetAddress()函数和getLocalPort()函数

  getInetAddress()函数用于获得服务器绑定的IP地址:和getLocalPort()函数用于获得服务器绑定的port,如果把port设为0,那么将由操作系统为服务器分配一个port(称为匿名port)。如下代码所示:
package com.xxx.serverSocket;import java.io.IOException;import java.net.InetAddress;import java.net.ServerSocket;public class ServerSocketTest {   public static void main(String[] args) throws IOException {       //把port设为0,请求连接的最大长度为3,IP设为127.0.0.1      ServerSocket serverSocket = new ServerSocket(0,3, InetAddress.getByName("127.0.0.1"));      System.out.println(serverSocket.getInetAddress());      System.out.println(serverSocket.getLocalPort());   }}运行结果如下所示:
https://img2024.cnblogs.com/blog/2485827/202601/2485827-20260126111548996-484687767.png

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

昆拗干 发表于 2026-2-2 04:58:15

分享、互助 让互联网精神温暖你我

魁睥 发表于 2026-2-3 05:08:17

感谢,下载保存了

均浇 发表于 2026-2-4 06:50:04

懂技术并乐意极积无私分享的人越来越少。珍惜

别萧玉 发表于 2026-2-4 09:00:15

不错,里面软件多更新就更好了

骆熙华 发表于 2026-2-5 08:31:01

新版吗?好像是停更了吧。

诘琅 发表于 2026-2-6 09:49:39

这个有用。

碛物 发表于 2026-2-7 04:44:11

喜欢鼓捣这些软件,现在用得少,谢谢分享!

嗣伐 发表于 2026-2-7 05:52:05

鼓励转贴优秀软件安全工具和文档!

羽桑 发表于 2026-2-7 22:04:43

新版吗?好像是停更了吧。

嫁蝇 发表于 2026-2-9 07:05:34

感谢分享

科元料 发表于 2026-2-9 10:58:08

感谢,下载保存了

荪俗 发表于 2026-2-9 16:24:06

不错,里面软件多更新就更好了

蔬陶 发表于 2026-2-9 16:49:01

这个有用。

赏听然 发表于 2026-2-9 22:39:54

热心回复!

眺愤 发表于 2026-2-10 14:10:29

分享、互助 让互联网精神温暖你我

蒙飘 发表于 2026-2-11 18:02:56

感谢发布原创作品,程序园因你更精彩

红弘丽 发表于 2026-2-11 21:05:52

感谢分享,学习下。

纪音悦 发表于 2026-2-12 00:13:41

不错,里面软件多更新就更好了

袋岖荤 发表于 2026-2-13 06:51:17

鼓励转贴优秀软件安全工具和文档!
页: [1] 2
查看完整版本: 1、ServerSocket简单介绍