Java 教程
- Java - 首页
- Java - 概述
- Java - 历史
- Java - 特性
- Java 与 C++
- JVM - Java 虚拟机
- Java - JDK 与 JRE 与 JVM
- Java - Hello World 程序
- Java - 环境搭建
- Java - 基本语法
- Java - 变量类型
- Java - 数据类型
- Java - 类型转换
- Java - Unicode 系统
- Java - 基本运算符
- Java - 注释
- Java - 用户输入
- Java - 日期和时间
Java 控制语句
- Java - 循环控制
- Java - 决策制定
- Java - If-else
- Java - Switch
- Java - For 循环
- Java - For-Each 循环
- Java - While 循环
- Java - do-while 循环
- Java - Break
- Java - Continue
面向对象编程
- Java - OOPs 概念
- Java - 对象和类
- Java - 类属性
- Java - 类方法
- Java - 方法
- Java - 变量作用域
- Java - 构造函数
- Java - 访问修饰符
- Java - 继承
- Java - 聚合
- Java - 多态
- Java - 重写
- Java - 方法重载
- Java - 动态绑定
- Java - 静态绑定
- Java - 实例初始化块
- Java - 抽象
- Java - 封装
- Java - 接口
- Java - 包
- Java - 内部类
- Java - 静态类
- Java - 匿名类
- Java - 单例类
- Java - 包装类
- Java - 枚举
- Java - 枚举构造函数
- Java - 枚举字符串
Java 内置类
Java 文件处理
Java 错误和异常
- Java - 异常
- Java - try-catch 块
- Java - try-with-resources
- Java - 多重 catch 块
- Java - 嵌套 try 块
- Java - Finally 块
- Java - throw 异常
- Java - 异常传播
- Java - 内置异常
- Java - 自定义异常
Java 多线程
- Java - 多线程
- Java - 线程生命周期
- Java - 创建线程
- Java - 启动线程
- Java - 线程连接
- Java - 线程命名
- Java - 线程调度器
- Java - 线程池
- Java - 主线程
- Java - 线程优先级
- Java - 守护线程
- Java - 线程组
- Java - 关闭钩子
Java 同步
Java 网络
- Java - 网络
- Java - 套接字编程
- Java - URL 处理
- Java - URL 类
- Java - URLConnection 类
- Java - HttpURLConnection 类
- Java - Socket 类
- Java - 泛型
Java 集合
Java 接口
Java 数据结构
Java 集合算法
高级 Java
- Java - 命令行参数
- Java - Lambda 表达式
- Java - 发送电子邮件
- Java - Applet 基础
- Java - Javadoc 注释
- Java - 自动装箱和拆箱
- Java - 文件不匹配方法
- Java - REPL (JShell)
- Java - 多版本 Jar 文件
- Java - 私有接口方法
- Java - 内部类菱形运算符
- Java - 多分辨率图像 API
- Java - 集合工厂方法
- Java - 模块系统
- Java - Nashorn JavaScript
- Java - Optional 类
- Java - 方法引用
- Java - 函数式接口
- Java - 默认方法
- Java - Base64 编码解码
- Java - Switch 表达式
- Java - Teeing 收集器
- Java - 微基准测试
- Java - 文本块
- Java - 动态 CDS 档案
- Java - Z 垃圾收集器 (ZGC)
- Java - 空指针异常
- Java - 打包工具
- Java - 密封类
- Java - 记录类
- Java - 隐藏类
- Java - 模式匹配
- Java - 紧凑数字格式化
- Java - 垃圾回收
- Java - JIT 编译器
Java 杂项
- Java - 递归
- Java - 正则表达式
- Java - 序列化
- Java - 字符串
- Java - 进程 API 改进
- Java - 流 API 改进
- Java - 增强的 @Deprecated 注解
- Java - CompletableFuture API 改进
- Java - 流
- Java - 日期时间 API
- Java 8 - 新特性
- Java 9 - 新特性
- Java 10 - 新特性
- Java 11 - 新特性
- Java 12 - 新特性
- Java 13 - 新特性
- Java 14 - 新特性
- Java 15 - 新特性
- Java 16 - 新特性
Java API 和框架
Java 类参考
- Java - Scanner
- Java - 数组
- Java - 字符串
- Java - Date
- Java - ArrayList
- Java - Vector
- Java - Stack
- Java - PriorityQueue
- Java - LinkedList
- Java - ArrayDeque
- Java - HashMap
- Java - LinkedHashMap
- Java - WeakHashMap
- Java - EnumMap
- Java - TreeMap
- Java - IdentityHashMap
- Java - HashSet
- Java - EnumSet
- Java - LinkedHashSet
- Java - TreeSet
- Java - BitSet
- Java - Dictionary
- Java - Hashtable
- Java - Properties
- Java - Collection
- Java - Array
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!