当前位置: 首页 > news >正文

【Java】网络编程基础与聊天室架构分析

IP 和 端口号

IP 用于标识网络中的主机 , 是如计算机 , 路由器等网络层设备的地址 .

端口号用于标识主机上运行的具体进程或服务 , 是传输层的逻辑接口 .

常见的 IPv4 地址为 32 位长 , 通常写成点分十进制形式 , 如 192.168.1.100 . IPv4 地址范围从 0.0.0.0255.255.255.255 , 其中较为特殊的是 回环地址 127.0.0.1 , 表示当前设备本身 .

端口号为 16 位整数 . 取值范围 0 - 65535 , 其中 0 - 1023 为通常由操作系统保留的系统端口,1024 - 65535 为用户或动态分配的端口 .

IP 类似于主机的门牌号 , 确定访问网络的设备的具体地址 . 端口号类似于门牌上的门或信箱 , 用来区分该主机上的不同网络服务 .

TCP 和 UDP

TCP 是一种面向连接的可靠传输协议 . TCP 在传输前需要经过三次握手建立连接 , 传输过程中提供错误校验 , 重传 , 顺序控制 , 流量控制和拥塞控制 , 确保数据无差错 , 不丢失 , 不重复 , 按序到达 .

因此 TCP 适用于对数据完整性和准确性要求较高的场景 , 如文件传输 , 电子邮件 , Web 浏览等 . 由于功能开销大 , TCP 头部长度固定为 20 字节以上 , 传输成本较高 .

UDP 是一种无连接的不可靠传输协议 . UDP 发送数据前不建立连接 . 不提供重传和顺序保证 , 只尽最大努力交付 . UDP 头部只有 8 字节 . 开销较小 .

因此 UDP 适用于实时性要求高 , 对丢包容忍度较大的场景 , 如网络语音 , 视频会议 , 在线游戏 , DNS查询等 .

TCP 三次握手与四次挥手

TCP 使用三次握手的过程来建立可靠的连接 , 确保通信双方具备收发能力 , 并提前协商好消息传输的顺序 .

其流程如下 :

  1. 客户端向服务器发送连接请求 , 表明希望建立通信 .
  2. 服务器收到请求后 , 回复一个应答 , 表示同意连接 , 同时也发出自己的连接请求 .
  3. 客户端再回应一个确认消息 , 表示双方可以开始通信 .

至此 , 客户端和服务器之间的连接正式建立 , 可以开始稳定的数据传输 .

而连接的断开则采用四个步骤进行 , 目的是让双方都有机会完成剩余的数据发送 , 避免信息丢失 .

关闭流程如下 :

  1. 一方先提出断开连接的请求 .
  2. 另一方收到后 , 先表示收到了请求 , 但还会继续发送剩余的数据 .
  3. 等数据发完后 , 再向对方表示自己也准备断开 .
  4. 对方再确认一次 , 并稍作等待 , 确保断开消息被成功收到 , 然后才完全关闭连接 .

这种方式确保了通信中没有遗漏或突然中断 , 体现了 TCP 协议核心安全特性 .

Java TCP通信

Java 使用 ServerSocket 和 Socket 类实现 TCP 通信 . 服务器端代码示例 :

// Server.java - 服务器端
ServerSocket server = new ServerSocket(12345);      // 在端口12345监听
Socket client = server.accept();                   // 接受客户端连接
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));   // 读客户端消息
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); // 写出消息到客户端
String msg = in.readLine();    // 读取一行文本
out.write("服务器收到了: " + msg + "\n");
out.flush();

客户端代码示例 :

// Client.java - 客户端
Socket socket = new Socket("localhost", 12345);     // 连接到本机12345端口
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 写消息到服务器
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));  // 读服务器回应
out.write("你好,服务器!\n");  
out.flush();
String response = in.readLine();  // 读取服务器回复
System.out.println("服务器说: " + response);

Java UDP通信

Java 使用 DatagramSocket 类和 DatagramPacket 类实现 UDP 通信。

发送数据的步骤包括 : 创建 DatagramSocket 和 DatagramPacket , 调用 send() 方法发送 , 最后关闭 Socket .

DatagramSocket ds = new DatagramSocket(); // 不指定端口,由系统随机分配
String str = "Hello UDP";
byte[] data = str.getBytes();
InetAddress addr = InetAddress.getByName("localhost");
int port = 12345;
DatagramPacket dp = new DatagramPacket(data, data.length, addr, port);
ds.send(dp);  // 发送数据包
ds.close();

接收数据的步骤包括 : 创建带监听端口的 DatagramSocket , 创建空的 DatagramPacket 作为接收容器 , 调用 receive() 方法接收数据包 , 从 DatagramPacket 中提取数据并解析 .

DatagramSocket ds = new DatagramSocket(12345); // 监听12345端口
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);  // 接收数据包(阻塞等待)
String received = new String(dp.getData(), 0, dp.getLength(), "UTF-8");
System.out.println("收到UDP消息: " + received);
ds.close();

该示例中,发送端通过DatagramPacket指定目标IP和端口发送消息;接收端通过绑定端口的DatagramSocket接收并解析数据包。

C/S 与 P2P

局域网聊天室中常用的两种架构是 **客户端-服务器 C/S 模式 **和 点对点 P2P 模式 .

C/S : 所有客户端都连接到一台中央服务器 , 客户端之间不直接通信 , 而是通过服务器转发信息 . 服务器负责维护在线用户列表 , 接收并广播消息给各客户端 , 实现群聊功能 .

该架构优点是实现简单 , 便于集中管理和广播消息 ; 缺点是服务器承载较大负载 , 存在单点故障风险 .

P2P : 每个节点既可作为客户端也可作为服务器 , 节点之间直接连接通信 . 常见的做法是让所有客户端先向中心服务器登记地址 , 获取其他在线节点列表 .请求通信时 , 客户端直接连接目标节点进行点对点聊天 . 登录后 , 客户端还会启动一个监听线程 , 接收其他节点的连接请求 .

P2P架构的优点是没有单点服务器 , 节点可以更灵活扩展 : 缺点是实现较为复杂 , 节点需要维护对等连接 , 有时需要处理网络地址转换等问题 .

特性C/S架构P2P架构
连接方式客户端主动连接服务器每个节点同时监听和主动连接其他节点
消息转发所有消息先汇集到服务器 , 由服务器转发给目标客户端或广播客户端之间直接通信 , 发送方直接将消息发给目标节点
连接维护服务器维护所有客户端的连接列表 , 统一管理上下线每个客户端维护自身与其他节点的连接或地址列表 , 节点自治

上述区别在代码实现上也有所体现 :

  1. C/S 服务器端使用 ServerSocket 接受客户端连接并保存客户端 Socket 列表 , 客户端统一与服务器的 Socket 读写消息 ; P2P 每个客户端除了作为客户端启动连接 , 也要打开 ServerSocket 监听端口以接收其它客户端的连接请求 , 节点既是客户端也是服务器 .

  2. 消息转发逻辑方面 , C/S 由服务器集中转发 , 而 P2P 是点对点直接发送 .

  3. 连接维护方面 , C/S 由服务器负责跟踪所有连接 . P2P 则需要各节点自行维护已连接对等方的信息 .

http://www.dtcms.com/a/251378.html

相关文章:

  • 七 医学影像云平台-影像检验互联互认平台建设中遇到的问题
  • to avoid naming wrong index webpage for one website
  • 安卓9.0系统修改定制化____安卓9.0系统精简 了解系统app组件构成 系统app释义 常识篇 一
  • 前端api中使用data传参源码解释
  • InnoDB的undo日志的数据结构
  • 跨域问题之前后端解决办法
  • 中介者模式Mediator Pattern
  • NISP-PTE基础实操——SQL注入
  • Vue3 Pinia Store 生命周期管理
  • Mysql基础入门\期末速成
  • 5G NR PDCCH之CORESET交织映射
  • 25年泰康保险养老社招入职统一测评(心理、认知、潜质)北森真题题库、高分攻略
  • 【系统分析师】第4章-基础知识:计算机网络与分布式系统(核心总结)
  • 从0开始学习语言模型--Day02-如何最大化利用硬件
  • 什么是装饰器?
  • 紧急救援!Ubuntu崩溃修复大赛
  • 三次贝塞尔曲线,二次贝塞尔曲线有什么区别
  • 通达信 玄学首板 抓首版指标
  • 11.OpenCV—联合QT环境配置
  • PoE供电异常如何排查?
  • leetcode 搜索插入位置 java
  • ArcGIS中英文切换
  • 62-STM32的ISP一键下载电路
  • 华为OD机试_2025 B卷_磁盘容量排序(Python,100分)(附详细解题思路)
  • 语言模型是怎么工作的?通俗版原理解读!
  • 第六十四节:基于EasyOCR的中英文文本识别与图像标注技术研究
  • 微信小程序 按钮点击事件
  • 概率期望DP
  • Luckfox Pico Pi RV1106学习<4>:RV1106的帧率问题
  • 易语言模拟真人鼠标轨迹算法 - 非贝塞尔曲线