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

Java 实现 TCP 一发一收通信

在网络编程中,TCP(传输控制协议)凭借其可靠传输的特性,成为需要确保数据完整性场景的核心选择。本文将基于一段 Java 代码实例,全面解析 TCP 单向通信的实现逻辑,帮助开发者掌握 TCP 编程的基础框架与底层原理。

核心代码展示

以下是实现 TCP 单向通信的完整代码,包含客户端与服务器端两个部分:

客户端(Client)代码

package com.practical.agreement.tcp.tcp_1;
import java.io.OutputStream;
import java.net.Socket;
import java.io.DataOutputStream;
/*
@description:
@ClassName Client
@author chen
@create 2025-07-21 14:53
@Version 1.0
*/
public class Client
{public static void main(String[] args) throws Exception{// 1、创建Socket对象,并同时请求与服务端程序的连接。Socket socket = new Socket("127.0.0.1", 8888);// 2、从socket通信管道中得到一个字节输出流,用来发数据给服务端程序。OutputStream os = socket.getOutputStream();// 3、把低级的字节输出流包装成数据输出流DataOutputStream dos = new DataOutputStream(os);// 4、开始写数据出去了dos.writeUTF("发送数据----~~~~~~~");dos.close();// 5、释放连接资源socket.close(); // 释放连接资源}
}

服务器端(Server)代码

package com.practical.agreement.tcp.tcp_1;
import java.io.DataInputStream;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
@description:
@ClassName Server
@author chen
@create 2025-07-21 14:54
@Version 1.0
*/
public class Server
{public static void main(String[] args) throws Exception{System.out.println("-----服务端启动成功-------");// 1、创建ServerSocket的对象,同时为服务端注册端口。ServerSocket serverSocket = new ServerSocket(8888);// 2、使用serverSocket对象,调用一个accept方法,等待客户端的连接请求Socket socket = serverSocket.accept();// 3、从socket通信管道中得到一个字节输入流。InputStream is = socket.getInputStream();// 4、把原始的字节输入流包装成数据输入流DataInputStream dis = new DataInputStream(is);// 5、使用数据输入流读取客户端发送过来的消息String rs = dis.readUTF();System.out.println(rs);// 其实我们也可以获取客户端的IP地址System.out.println(socket.getRemoteSocketAddress());dis.close();socket.close();}
}

一、TCP 协议基础与代码功能解析

TCP 是一种面向连接的可靠传输协议,其核心特性体现在:

  • 连接导向:通信前必须通过 "三次握手" 建立连接
  • 可靠传输:通过序列号、确认应答、超时重传等机制保证数据完整
  • 流量控制:通过滑动窗口机制避免接收方缓冲区溢出
  • 拥塞控制:根据网络状况动态调整发送速率

本次展示的代码实现了 TCP 最基础的单向通信模式:客户端主动发起连接并发送一条字符串消息,服务器端接收消息后打印内容及客户端地址信息。该代码虽简单,却完整包含了 TCP 通信的核心流程,是理解复杂 TCP 应用的基础。

二、代码执行流程深度解析

1. 服务器端启动与等待连接

服务器端的运行遵循 "初始化 - 等待 - 处理" 的逻辑:

  1. 端口注册:通过new ServerSocket(8888)创建服务器端对象,同时向系统注册 8888 端口,用于监听客户端连接请求
  2. 阻塞等待:serverSocket.accept()方法会进入阻塞状态,直到有客户端发起连接请求,此时返回一个Socket对象,建立与客户端的专属通信管道
  3. 流初始化:从Socket中获取字节输入流InputStream,并包装为DataInputStream—— 这种包装能直接读取 Java 基本数据类型,简化字符串传输流程
  4. 数据读取:dis.readUTF()方法读取客户端发送的 UTF-8 编码字符串,该方法会严格按照writeUTF()的编码格式解析数据
  5. 资源释放:读取完成后关闭输入流和Socket,释放系统资源

2. 客户端连接与数据发送

客户端的执行流程体现了 TCP 的主动发起特性:

  1. 建立连接:new Socket("127.0.0.1", 8888)通过指定 IP 地址(本地回环地址)和端口号,向服务器端发起连接请求,底层会完成三次握手过程
  2. 输出流准备:获取Socket的字节输出流OutputStream,并包装为DataOutputStream,便于使用writeUTF()方法发送字符串
  3. 消息发送:dos.writeUTF()会先写入字符串长度(2 字节),再写入 UTF-8 编码的字节序列,确保服务器端能准确解析
  4. 连接关闭:发送完成后关闭输出流和Socket,触发四次挥手过程终止连接

三、TCP 通信的关键特性验证

通过代码运行可直观观察 TCP 的核心特性:

  • 连接导向:若先启动客户端会抛出Connection refused异常,证明必须先建立连接才能通信
  • 顺序传输:多次发送消息时(需修改代码为循环),服务器端接收顺序与发送顺序完全一致
  • 可靠交付:在网络不稳定环境下,TCP 会自动重传丢失的数据包,确保服务器端最终能完整接收

代码中socket.getRemoteSocketAddress()方法展示了 TCP 的双向地址感知能力,该方法返回客户端的 IP 地址和端口号(格式为/127.0.0.1:端口号),体现了 TCP 连接的端到端特性。

四、技术局限性与扩展方向

现有代码的局限性

  1. 单向通信:仅支持客户端向服务器端发送消息,无法实现双向交互
  2. 单连接处理:服务器端处理完一个连接后即关闭,无法同时服务多个客户端
  3. 无异常处理:未包含try-catch块,网络波动可能导致程序崩溃
  4. 资源释放问题:直接关闭流可能导致资源释放不彻底,建议使用 try-with-resources 语法

实用扩展方案

  1. 双向通信:在客户端添加输入流、服务器端添加输出流,实现消息互发
  2. 多客户端支持:使用多线程技术,主线程负责接收连接,子线程处理具体通信
  3. 异常处理增强:添加try-catch-finally块捕获IOException,确保资源正确释放
  4. 长连接保持:去除单次通信后关闭连接的逻辑,通过心跳机制维持长连接

五、TCP 通信的典型应用场景

尽管 TCP 存在连接建立延迟、开销较大等特点,但其可靠性使其在以下场景中不可替代:

  • 文件传输:FTP、SFTP 等协议基于 TCP 实现,确保文件传输完整
  • 金融交易:银行转账、支付系统等需保证交易指令准确无误
  • 邮件服务:SMTP、IMAP 等邮件协议依赖 TCP 确保邮件不丢失
  • HTTP 通信:网页浏览、API 调用等场景需要完整的内容传输

相比之下,视频通话、实时游戏等对延迟敏感的场景更适合 UDP,开发者需根据业务特性选择合适的传输协议。

总结

本文通过一段精简的 Java 代码,完整呈现了 TCP 单向通信的实现过程。从服务器端的端口监听,到客户端的连接发起,再到数据的编码传输,每一步都体现了 TCP 协议的核心设计思想。

掌握这段代码的原理后,开发者可逐步扩展出更复杂的 TCP 应用 —— 无论是多客户端聊天系统,还是文件传输工具,其底层都离不开本文阐述的基础流程。理解 TCP 的可靠性机制与代码实现的对应关系,是构建稳定网络应用的关键。

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

相关文章:

  • GitHub+Git新手使用说明
  • Unreal ARPG笔记
  • 讯飞输入法3.0.1742功能简介
  • SpringMVC学习笔记
  • vue3实现可视化大屏布局
  • 数组习题及答案
  • f4硬件配置spi
  • 一维DP深度解析
  • 三菱A1SJ PLC以太网模块:上位机与触摸屏高效通讯解决方案
  • 深入解析:如何在Kafka中配置Source和Sink连接器构建高效数据管道
  • 金仓数据库:融合进化,智领未来——2025年数据库技术革命的深度解析
  • 【Linux指南】Linux系统 -权限全面解析
  • Windows下编译libarchive
  • JavaWeb笔记四
  • 深入详解随机森林在医学图像质量评估中的应用与实现细节
  • OCR 身份识别:让身份信息录入场景更高效安全
  • PHP反序列化漏洞详解
  • 第十八节:第七部分:java高级:注解的应用场景:模拟junit框架
  • 【c++】leetcode5 最长回文子串
  • 【Project】ELK 7.17.16 日志分析系统部署
  • Day07_网络编程20250721(网络编程考试试卷)
  • 关于 URL 中 “+“ 号变成空格的问题
  • CentOS 7安装 FFmpeg问题可以按照以下步骤进行安装
  • Spring Boot 3核心技术面试指南:从迁移升级到云原生实战,9轮技术攻防(含架构解析)
  • Django实战:基于Django和openpyxl实现Excel导入导出功能
  • 基于python django的BOSS直聘网站计算机岗位数据分析与可视化系统,包括薪酬预测及岗位推荐,推荐算法为融合算法
  • 智能体性能优化:延迟、吞吐量与成本控制
  • django filter按两个属性 去重
  • JAVA面试宝典 -《 架构演进:从单体到 Service Mesh》
  • Go从入门到精通(26) - 一个简单web项目-实现服务注册