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.pswp.cn/diannao/92156.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/92156.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker-compose启动前后端分离项目(单机)

🌟docker-compose启动前后端 📁准备文件 xzs-mysql.sql(数据库脚本)xzs-3.9.0.jar(后端代码)application-prod.yml(后端配置文件)entry.sh(后端启动脚本)exam…

有关Mysql数据库的总结

MySQL概念MySQL的理论知识概念数据库就是用来存储和管理数据的仓库!数据库分类层次型数据库树型结构,一个子记录可以有一个父记录,一个父记录可以有多个子记录,类似一个二叉树,但是一个父节点可以不止两个子节点&#…

复制docker根目录遇到的权限问题

环境 ubuntu20.04, 普通用户使用sudo权限。 需求 linux系统上,默认的docker跟目录在/var/lib/docker目录下,但是根分区太小。想要将docker根目录挪到其它磁盘,防止以后镜像和容器增加后磁盘满了。 操作 先停止所有docker容器,然后…

git-子仓操作

为什么为什么要将代码仓作为子模块?有什么优势?精确版本控制:父仓记录子仓的commit哈希值,确保代码版本固定,避免隐式升级导致的兼容性问题模块化管理:将独立仓库作为子模块嵌入父仓,实现代码物…

代数——第5章——线性算子之应用(Michael Artin)

第 5 章 线性算子之应用 (Applications of Linear Operators) By relieving the brain from all unnecessary work, a good notation sets it free to concentrate on more advanced problems.( 通过减轻大脑所有不必要的工作,良好的符号可以让大脑集中精力解决…

Pytorch02:深度学习基础示例——猫狗识别

一、第三方库介绍库/模块功能torch提供张量操作、自动求导、优化算法、神经网络模块等基础设施。torchvision计算机视觉工具集,提供预训练模型、数据集、图像转换等功能。datasets (torchvision)用于加载常见数据集(如 ImageNet、CIFAR-10、MNIST&#x…

spring简单项目实战

项目路径 modelspackage com.qcby.demo1;import com.qcby.service.UserService; import com.qcby.service.UserServiceImpl;public class Dfactory {public UserService createUs(){System.out.println("实例化工厂的方式...");return new UserServiceImpl();} }pack…

ServBay for Windows 1.4.0 发布:新增MySQL、PostgreSQL等数据库自定义配置

各位 Windows 平台的开发者们, ServBay 始终致力于为您打造一个强大、高效且灵活的本地开发环境。距离上次更新仅过去短短一周,经过我们技术团队的快速开发,我们正式推出了 ServBay for Windows 1.4.0 版本。 专业开发者不仅需要一个能用的环…

python网络爬虫小项目(爬取评论)超级简单

python网络爬虫小项目(爬取评论)超级简单 学习python网络爬虫的完整路径: (第一章) python网络爬虫(第一章/共三章:网络爬虫库、robots.txt规则(防止犯法)、查看获取网页源代码)-…

本周大模型新动向:奖励引导、多模态代理、链式思考推理

点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入!01Iterative Distillation for Reward-Guided Fine-Tuning of Diffusion Models in Biomolecular Design本文提出了一种用于生物分子设计中奖励引导生成的扩散模型微调框架。扩散模型在建模复杂、高维数据分布方面…

JAVA+AI教程-第三天

我将由简入繁,由零基础到详细跟大家一起学习java---------------------------------------------------------------------01、程序流程控制:今日课程介绍02、程序流程控制:if分支结构if分支有三种形式,执行顺序就是先执行if&…

自定义命令行解释器shell

目录 一、模块框架图 二、实现目标 三、实现原理 四、全局变量 五、环境变量函数 六、初始化环境变量表函数 七、输出命令行提示符模块 八、提取命令输入模块 九、填充命令行参数表模块 十、检测并处理内建命令模块 十一、执行命令模块 十二、源码 一、模块框架图…

uniapp使用uni-ui怎么修改默认的css样式比如多选框及样式覆盖小程序/安卓/ios兼容问题

修改 uni-ui 多选框 (uni-data-checkbox) 的默认样式 在 uniapp 中使用 uni-ui 的 uni-data-checkbox 组件时,可以通过以下几种方式修改其默认样式: 方法一:使用深度选择器格式一:在页面的 style 部分使用深度选择器 >>>…

《Linux 环境下 Nginx 多站点综合实践:域名解析、访问控制与 HTTPS 加密部署》​

综合练习:请给openlab搭建web网站,网站需求: 1.基于域名www.openlab.com可以访问网站内容为 welcome to openlab!!, 2.给该公司创建三个子界面分别显示学生信息,教学资料和缴费网站,基于www.openlab.com/student 网站访…

网络基础1-11综合实验(eNSP):vlan/DHCP/Web/HTTP/动态PAT/静态NAT

注:在华为模拟器(eNSP)上做的实验其中,在内网实验:Vlan/DHCP/VWeb/HTTP,在外网实验:动态PAT/静态NAT一、拓扑结构1. 核心设备与连接设备接口连接对象VLAN/IP角色LSW2/LSW3Ethernet 0/0/1-2PC1/P…

Mac上安装Claude Code的步骤

以下是基于现有信息的简明安装指南,适用于macOS系统。请按照以下步骤操作: 前提条件 操作系统:macOS 10.15或更高版本。Node.js和npm:Claude Code基于Node.js,需安装Node.js 18和npm。请检查是否已安装: …

MybatisPlus-15.扩展功能-逻辑删除

一.逻辑删除配置逻辑删除的字段时,logic-delete-field字段配置的是逻辑删除的实体字段名。字段类型可以是boolean和integer。在java中默认是boolean类型。逻辑已删除值默认为1,而逻辑未删除值默认为0。当是1时代表已删除(1在数据库表中为true&#xff0c…

IDEA 同时修改某个区域内所有相同变量名

在 IntelliJ IDEA 中,同时修改某个区域内所有 相同变量名 的快捷键是: ✅ Shift F6(重命名变量) 但这个快捷键默认是 全局重命名,如果你想 仅修改某个方法或代码块内的变量名,可以这样做:&…

Telink BLE 低功耗学习

低功耗管理(Low Power Management)也可以称为功耗管理(Power Management),本⽂档中会简称为PM。Telink低功耗解惑我查阅多连接SDK开发手册时,低功耗管理章节看了两三遍也没太明白,有以下几个问题…

设备管理系统(MMS)如何在工厂MOM功能设计和系统落地

一、核心系统功能模块设备管理系统围绕设备全生命周期管理设计,涵盖基础数据管理、设备运维全流程管控及统计分析功能,具体如下:基础数据管理设备与备件台账:包含设备台账(设备编号、识别码、型号、生产日期等&#xf…