Java 教程

Java 控制语句

面向对象编程

Java 内置类

Java 文件处理

Java 错误和异常

Java 多线程

Java 同步

Java 网络

Java 集合

Java 接口

Java 数据结构

Java 集合算法

高级 Java

Java 杂项

Java API 和框架

Java 类参考

Java 有用资源

Java - 套接字编程



Java 中的套接字编程

套接字使用 TCP 提供两台计算机之间的通信机制。客户端程序在其通信端创建套接字,并尝试将该套接字连接到服务器。

建立连接后,服务器在其通信端创建套接字对象。客户端和服务器现在可以通过写入和读取套接字来进行通信。

java.net.Socket 类 表示套接字,并且 java.net.ServerSocket 类为服务器程序提供了一种机制来侦听客户端并与之建立连接。

Java 中套接字编程的步骤

使用套接字在两台计算机之间建立 TCP 连接时,会发生以下步骤:

  • 服务器实例化一个 ServerSocket 对象,表示要进行通信的端口号。

  • 服务器调用 ServerSocket 类的 accept() 方法。此方法一直等到客户端连接到给定端口上的服务器。

  • 服务器等待后,客户端实例化一个 Socket 对象,指定要连接到的服务器名称和端口号。

  • Socket 类的构造函数尝试将客户端连接到指定的服务器和端口号。如果建立了通信,则客户端现在拥有一个能够与服务器通信的 Socket 对象。

  • 在服务器端,accept() 方法返回对服务器上连接到客户端套接字的新套接字的引用。

建立连接后,可以使用 I/O 流进行通信。每个套接字都具有 OutputStream 和 InputStream。客户端的 OutputStream 连接到服务器的 InputStream,而客户端的 InputStream 连接到服务器的 OutputStream。TCP 是一种双向通信协议,因此数据可以同时通过这两个流发送。

Java 套接字编程的优点

  • 平台独立性 - Java 套接字的最大优点之一是它们是平台独立的。这意味着相同的 Java 代码可以在多个操作系统和设备上运行,无需修改。这使得跨不同系统轻松部署基于网络的应用程序,并确保应用程序可以在不同的设备上运行,而无需平台特定的代码。

  • 易于使用 - Java 套接字也相对易于使用,即使对于网络编程新手也是如此。Java API 提供了一个简单一致的接口来创建和管理套接字,这使得轻松实现基于网络的应用程序,而无需了解底层网络协议。

  • 可扩展性 - Java 套接字具有高度可扩展性,使其适用于大型基于网络的应用程序。它们可以轻松处理数千个同时连接,并且可用于创建能够处理高流量的分布式系统。

  • 安全性 - Java 套接字提供对安全通信的内置支持,包括 SSL 和 TLS 加密。这使得轻松创建安全的基于网络的应用程序,并确保敏感数据在传输过程中得到保护。

  • 多线程 - Java 套接字支持多线程,这意味着多个线程可以同时处理多个连接。这提高了基于网络的应用程序的性能,并允许它们处理大量请求而不会过载。

Java 套接字编程的缺点

  • 复杂性 - 虽然 Java 套接字相对易于使用,但它们在实现时仍然可能很复杂,特别是对于网络编程新手而言。这种复杂性可能使调试和排除基于网络的应用程序的故障变得困难,这可能既费时又令人沮丧。

  • 延迟 - Java 套接字可能会导致基于网络的应用程序出现延迟,尤其是在处理大量数据时。对于需要实时通信的应用程序(例如在线游戏或视频会议),这可能是一个问题。

  • 资源密集型 - Java 套接字可能是资源密集型的,尤其是在处理大量连接或大量数据时。对于资源有限的系统(例如移动设备或嵌入式系统),这可能是一个问题。

  • 协议支持有限 - Java 套接字支持有限数量的网络协议,这对于某些类型的基于网络的应用程序来说可能是一个限制。这可能使创建需要使用专有协议与其他系统通信的应用程序变得困难。

  • 潜在的安全漏洞 - 与任何基于网络的应用程序一样,Java 套接字容易受到安全威胁,例如黑客攻击和中间人攻击。在设计和实现基于 Java 套接字的系统时,必须注意安全性,以确保敏感数据得到保护,并识别和解决潜在的漏洞。

套接字编程应用程序

  • 聊天应用程序 − Java 套接字常用于创建聊天应用程序,例如即时消息程序和在线聊天室。这些类型的应用程序通常使用客户端-服务器架构,其中客户端连接到中央服务器以发送和接收消息。

  • 文件传输应用程序 − Java 套接字也可用于创建文件传输应用程序,例如对等文件共享程序。这些类型的应用程序使用对等架构,其中每个设备既充当客户端又充当服务器。这允许设备之间直接通信,从而可以提高文件传输的速度和可靠性。

  • 远程控制应用程序 − Java 套接字也可用于创建远程控制应用程序,例如远程桌面软件。这些类型的应用程序使用客户端-服务器架构,其中客户端连接到远程服务器以控制服务器的桌面。这允许用户从任何具有互联网连接的设备访问和控制其桌面。

  • 多人游戏 − Java 套接字也常用于创建多人游戏,例如在线角色扮演游戏和第一人称射击游戏。这些类型的应用程序通常使用客户端-服务器架构,其中客户端连接到中央服务器以玩游戏。服务器充当客户端之间的中介,处理通信和游戏逻辑。

  • 物联网应用 − Java 套接字也可用于物联网 (IoT) 应用程序,例如智能家居系统。这些类型的应用程序使用客户端-服务器架构,其中物联网设备连接到中央服务器以发送和接收数据。这允许远程监控和控制设备,以及数据收集和分析。

套接字编程示例

示例:套接字客户端

以下 GreetingClient 是一个客户端程序,它使用套接字连接到服务器并发送问候语,然后等待响应。

// File Name GreetingClient.java
import java.net.*;
import java.io.*;

public class GreetingClient {

   public static void main(String [] args) {
      String serverName = args[0];
      int port = Integer.parseInt(args[1]);
      try {
         System.out.println("Connecting to " + serverName + " on port " + port);
         Socket client = new Socket(serverName, port);
         
         System.out.println("Just connected to " + client.getRemoteSocketAddress());
         OutputStream outToServer = client.getOutputStream();
         DataOutputStream out = new DataOutputStream(outToServer);
         
         out.writeUTF("Hello from " + client.getLocalSocketAddress());
         InputStream inFromServer = client.getInputStream();
         DataInputStream in = new DataInputStream(inFromServer);
         
         System.out.println("Server says " + in.readUTF());
         client.close();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

示例:套接字服务器

以下 GreetingServer 程序是一个服务器应用程序示例,它使用 Socket 类在命令行参数指定的端口号上侦听客户端 −

// File Name GreetingServer.java
import java.net.*;
import java.io.*;

public class GreetingServer extends Thread {
   private ServerSocket serverSocket;
   
   public GreetingServer(int port) throws IOException {
      serverSocket = new ServerSocket(port);
      serverSocket.setSoTimeout(10000);
   }

   public void run() {
      while(true) {
         try {
            System.out.println("Waiting for client on port " + 
               serverSocket.getLocalPort() + "...");
            Socket server = serverSocket.accept();
            
            System.out.println("Just connected to " + server.getRemoteSocketAddress());
            DataInputStream in = new DataInputStream(server.getInputStream());
            
            System.out.println(in.readUTF());
            DataOutputStream out = new DataOutputStream(server.getOutputStream());
            out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
               + "\nGoodbye!");
            server.close();
            
         } catch (SocketTimeoutException s) {
            System.out.println("Socket timed out!");
            break;
         } catch (IOException e) {
            e.printStackTrace();
            break;
         }
      }
   }
   
   public static void main(String [] args) {
      int port = Integer.parseInt(args[0]);
      try {
         Thread t = new GreetingServer(port);
         t.start();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

编译客户端和服务器,然后按如下方式启动服务器 −

$ java GreetingServer 6066
Waiting for client on port 6066...

按如下方式检查客户端程序 −

输出

$ java GreetingClient localhost 6066
Connecting to localhost on port 6066
Just connected to localhost/127.0.0.1:6066
Server says Thank you for connecting to /127.0.0.1:6066
Goodbye!
广告