首页/新闻资讯/正文详情

TCP/UDP

发布时间:2026/11/5 13:57:48 来源:云帆数科 栏目:资讯中心
TCP/UDP
传输层端口号0~65535 但是1~1023基本被占用了而且占用的程序好像活着的不多了用的话基本就是从1024开始往后排。常用的端口号ssh:22 Liunx的远程连接http:80https:443ftp:21文件传输协议telnet:23(明文远程连接)DNS53常问的:一个进程可以bind多个端口号一个进程里面是有好多个线程每一个线程bind一个 端口号是可以的。一个端口号是不可以被多个进程bind的。五元组源ip 目的ip 源端口 目的端口 协议类型tcp/udpUDP无连接不可靠传输面向数据报全双工┌─────────┬──────────┬─────────┬────────────┐│ 16位源端口 │16位目的端口 │ 16位长度 │ 16位校验和 │ ← 首部 8 字节├─────────┴──────────┴─────────┴────────────┤│ 数据payload │└────────────────── ─────────────────────────┘16位长度就是传输的数据的大小 16位bit—64kb 可以传的东西大小非常小如果需要传输大的数据大于64kb只能分多次去发送去拆包再组包。16位校验和数学公式验证这个传输前后的数据有没有受损坏。UDP 报头中的校验和是个 2 字节的数据使用于不容易丢包的地方对传输效率高的地方传小的数据的地方。代码实现服务端UdpEchoServerpackage Socket; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException; public class UdpEchoServer { // 服务端使用的 DatagramSocket 对象 private DatagramSocket socket null; // 构造方法端口号 public UdpEchoServer(int prot) throws SocketException { socket new DatagramSocket(prot); } //启动服务端 //处理客户端请求 public void start() throws IOException { System.out.println(Server start); while (true){ //作为服务器先接收信息 DatagramPacket requsetPacket new DatagramPacket(new byte[1024] , 1024); socket.receive(requsetPacket); //得到的数据报转化为string类型的 String request new String(requsetPacket.getData() ,0, requsetPacket.getLength()); //在服务端去处理这个数据 String response possen(request); //重新封装返回的数据报 DatagramPacket responsePacket new DatagramPacket(response.getBytes(),response.getBytes().length, requsetPacket.getSocketAddress()); //发送数据报 socket.send(responsePacket); //打印日志 System.out.printf([%s:%d] res:%s rep:%s \n , requsetPacket.getAddress().toString(),requsetPacket.getPort(), request,response); } } //处理业务逻辑 public String possen(String request) { return request; } //主方法 public static void main(String[] args) throws IOException { UdpEchoServer udpEchoServer new UdpEchoServer(9999); udpEchoServer.start(); } }客户端UdpEchoClientpackage Socket; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.util.Scanner; public class UdpEchoClient { // 服务端使用的 DatagramSocket 对象 private DatagramSocket socket null; // 服务器端口 private int serverPort; // 服务器ip private String serverIp; // 构造方法 创建客户端 需要服务器的端口和ip public UdpEchoClient(String serverIp ,int serverPort ) throws SocketException { socket new DatagramSocket(); this.serverPort serverPort; this.serverIp serverIp; } // 启动客户端的 public void start() throws IOException { Scanner scanner new Scanner(System.in); System.out.println(client start); while (true){ //作为客户端需要先发送 System.out.printf(-); //读取用户输入 String text scanner.nextLine(); //封装成数据包发送 需要服务器的ip和端口 DatagramPacket response new DatagramPacket(text.getBytes(),text.getBytes().length, InetAddress.getByName(this.serverIp),this.serverPort); //发送数据包 socket.send(response); //接收服务器回显的数据包 需要一个数据包来接收 DatagramPacket resquestPath new DatagramPacket(new byte[1024] , 1024); socket.receive(resquestPath); //将数据包中的数据转换成字符串 String ressquest new String(resquestPath.getData(),0, resquestPath.getLength()); //打印输出 System.out.println(ressquest); } } // 程序的入口的 public static void main(String[] args) throws IOException { UdpEchoClient udpEchoClient new UdpEchoClient(127.0.0.1,9999); udpEchoClient.start(); } }TCP有连接可靠传输面向字节流全双工0 15 16 31 ------------------------------------------------ | 16位源端口号 | 16位目的端口号 | 第1行 ------------------------------------------------ | 32位序号 (seq) | 第2行 --------------------------------------------------- | 32位确认序号 (ack) | 第3行 ------------------------------------------- |4位首部 |保留(6)|URG|ACK|PSH|RST|SYN|FIN|16位窗口 | 第4行 | 长度 | | | | | | | | 大小 | ------------------------------------------- | 16位检验和 | 16位紧急指针 | 第5行 ------------------------------------------------ | 选项长度可变0~40字节 | 第6行 --------------------------------------------------- | 数据 (payload) | 第7行 ---------------------------------------------------16位检验和和UDP一样4位报头长度4bit范围是0~15 也就是0~4*1560必须的4的倍数啊6位标识符ack(确认报文) ret(复位报文) syn(同步报文) fin(结束报文)基于可靠性的特性1.确认应答每次的发送数据都会收到一个ack也会携带下一个的起始点。2.超时重传 --- 可靠传输丢包数据丢了ack丢了重新传报都是因为没有传回的ack而需要重传的超时时间指数递增累计到一定次数 → 认为网络/对端异常强制关闭连接如果是数据丢了重新传无事发生如果是ack丢了重新传数据会重复是根据传数据的序列号去重3.连接管理连接的时候三次握手也可以是四次握手 发ack 和 syn 分开发listen准备就绪establisten:连接完毕可以通信了syn_sent:发送连接很快syn_rcvd:接收连接很快断开连接的时候四次挥手服务器应用层是否还有未发送的数据决定了是不是可以 合并SYN和ACKFIN_WAIT_1:主动关闭方发出的FIN后还没有收到ACK的状态。FIN_WAIT_2:主动关闭方收到ACK还没有收到FIN的状态TIME_WAIT:主动关闭方收到FIN的状态等待 2MSL 后进入 CLOSEDCLOSE_WAIT:被动关闭方收到FIN的进入还没有调用CLOSE()的方法状态。LAST_ACK:已发FIN等最后ACKCLOSED:关闭连接的状态。4.滑动窗口每次发一个数据就需要恢复一次ACK,影响效率会变慢可以一组一组发ACK返回下 一个数据的序号。会出现的问题ACK丢失虽然传输期间有一部分ACK丢失但是由于ACK返回的都是下一个的序号后面最后的 ACK如果是正常的那就是其实证明了数据的传输没有问题数据丢失数据丢失ACK返回的一直都是确实的的序号。(问题不大)处理数据的时候都是先进入接收方的数据缓冲区当需要不不连续的时 候后面的数 据就先放到缓存器等待等正确需要数据序号来了再继续处理排序去重 也是都是在数 据缓冲区里面处理的快重传发送端连续收到几次相同的ACK如好几次ACK1001立刻重传丢失的数 据不用等超时。补齐后回复的是总的数据的下一个序号。5.流量控制16位窗口大小里面的就是ACK也返回的是数据缓存器剩余的空间。问题如果此时的缓存器里面的空间为0了就不发了那发送方咋知道啥时候有空间。A会每隔一段时间发送一个空的报文窗口探测{去“敲门”问 B“哥们腾出空间了吗现在能收多少”}。发给BB如果有空间就回复空间 了如果还是没有B还是返回0.6.拥塞控制传输数据嘛一下子太大的话会导致数据丢失。先设定一个阈值最开始从1份开始 -----份不是固定值 是自己设置的纵坐标嘛就是阻塞窗口 实际发送量 min(拥塞窗口, 接收窗口)到了阈值之前发送的数据大小都是以指数增长。到了阈值还没有阻塞的话后面开始匀速增长。如果期间数据缓存器产生了阻塞开始缩小窗口设定新的阈值为产生阻塞位置一半老办法直接回到1份继续上述的过程新办法到达新的阈值的位置开始匀速增长7.延迟应答ACK不是看到一组就返回一次而且延迟回复让数据多传几次再去返回可以提高效率减少了ACK报的数量延迟 时间后窗口变大了发送方就能发更多吞吐量就上去了限制不能死等受“每2个包回一次”和“最大延迟200ms”的限制。8.捎带应答类似建立连接的时候三次握手第二次是就是服务端返回了syn和ack 就是捎带应答。每次回答的时候如果还是别的数据可以顺带一个发送。9.面向字节流---粘包问题TCP是面向字节流的不像UDP是有自己的DatagramPacket以至于发送的时候会边界丢失不知道那些字节组合是一个完整的数据解决分隔符去限制当输入到什么时候就判定为输入完毕就是一组数据处理的时候也是当出现这个符号的时候前面就是完整的数据。比如\n或者\r\n作为边界数据开头属性在每个发的数据前面加上字符的长度处理就按长度处理。10.异常处理1.进程奔溃退出的状态就是和正常的四次挥手状态一样。虽然是进程没有了但是连接还是在的。2.主机正常关机强制结束所有的进程电脑关机会显示有一个正在阻止关机下面的强制关 机正常的四次挥手关闭是为了让双方都删除对方的信息服务端发好多了FIN后发现一直都没有回应那就算了直接单方面断开删除客户端的连接信息。3.主机断电关机当接收方的直接断电跑路此时发送方发FIN或者别的什么都不会有回应的无论多少次都是超时红色感叹号就需要放弃了最后再发RST复位报文就算放弃了都是陌生人了。4.网线断开属于是双方无法正常通信 但是双方不知道是什么原因陌生人了还是有事 了发送方会发一个”心跳包“ --什么都没有只为了让对方返回ACK如果没有回复就断开连接删除信息不理我算了删了代码实现服务端TcpEchoServerpackage Socket; import jdk.jshell.spi.ExecutionControl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class TcpEchoServer { // 服务端使用的 ServerSocket 对象 private ServerSocket serverSocket null; //构造方法需要服务器端口 public TcpEchoServer(int port) throws IOException { serverSocket new ServerSocket(port); } public void start() throws IOException { System.out.println(TCPserver.start); // ExecutorService cached Executors.newCachedThreadPool(); while (true){ //把已经连接的客服端弄成socker Socket socket serverSocket.accept(); //进入这个方法 cached.submit(() - processConnection(socket)); //也可以用多线程来运行 // Thread thread new Thread(() - { // processConnection(socket); // }); } } private void processConnection(Socket socket) { System.out.printf([%s:%d]上线了\n ,socket.getInetAddress(),socket.getPort()); try { //负责读写的 InputStream inputStream socket.getInputStream(); OutputStream outputStream socket.getOutputStream(); //负责发送和接收的 Scanner scanner new Scanner(inputStream); PrintWriter writer new PrintWriter(outputStream); while (true){ if (!scanner.hasNext()){ System.out.printf([%s:%d]下线了\n ,socket.getInetAddress(),socket.getPort()); break; } //接收的东西 String request scanner.next(); //处理一下 准备回显回去 String response process(request); //发回去从服务器到客户端 writer.println(response); // 刷新缓冲区 确保数据被发送出去 writer.flush(); System.out.printf([%s:%d] req:%s res:%s\n , socket.getInetAddress(),socket.getPort(),request,response); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { // 关闭连接 socket.close(); } catch (IOException e) { throw new RuntimeException(e); } } } public String process(String request ) { return request; } public static void main(String[] args) throws IOException { TcpEchoServer tcpEchoServer new TcpEchoServer(9999); tcpEchoServer.start(); } }客户端TcpEchoClientpackage Socket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.util.Scanner; import java.util.ServiceConfigurationError; public class TcpEchoClient { // 客户端使用的 Socket 对象 private Socket socket null; //构造方法 需要服务器的ip和端口 public TcpEchoClient(String serverIp , int serverPort) throws IOException { socket new Socket(serverIp , serverPort); } public void start(){ System.out.println(client start!); try{ //负责读写的 InputStream inputStream socket.getInputStream(); OutputStream outputStream socket.getOutputStream(); //负责处理读写的 Scanner scannerRead new Scanner(inputStream); PrintWriter writer new PrintWriter(outputStream); //负责输入的 Scanner scanner new Scanner(System.in); while (true){ System.out.printf(-); String request scanner.next(); //发给服务器的东西 writer.println(request); writer.flush(); //接收回显 if (!scannerRead.hasNext()){ break; } //读回显打印 String response scannerRead.next(); System.out.println(response); } }catch (IOException E){ E.printStackTrace(); } } public static void main(String[] args) throws IOException { TcpEchoClient tcpEchoClient new TcpEchoClient(127.0.0.1, 9999); tcpEchoClient.start(); } }

相关推荐

算力网络是什么?从算力路由到算网调度的技术体系解读
算力网络是什么?从算力路由到算网调度的技术体系解读

算力网络是什么?先给一个直接回答:它是以算为中心、网为根基、智为引擎的新型信息基础设施,核心不是“把算力搬来搬去”,而是算力与网络的联合调度。本文拆解算力路由、算网调度技术体系,以及它和传统网络、云计算的区… · 2026/11/5 2:36:27

算力网络不止是建设:剖析东数西算下三大落地卡点与实施路径
算力网络不止是建设:剖析东数西算下三大落地卡点与实施路径

算力网络如何落地,关键不在“再建多少算力”,而在“把已经建好的算力用起来”。西部部分枢纽节点上架率不足30%,全国智算中心平均算力使用率约三成,两组数据放在一起,东数西算当前的矛盾已经从“建不建”转向“用不用”… · 2026/11/4 9:47:14

第 6 篇|落地演进:存量 SaaS 向 AI-Native 基座平滑迁移
第 6 篇|落地演进:存量 SaaS 向 AI-Native 基座平滑迁移

承接前面五篇,我们已经厘清范式负债、基座三驾马车、区分基座与低代码、以及基座之上的智能产品与智能生产体系。前面只讲清了终态应该是什么样,但没有回答一个绕不开的现实问题:对于存在多版本历史存量、大量在运业务域的成熟 SaaS企业&… · 2026/11/4 6:03:27

GD32E10x官方例程入门:从GPIO点灯到串口调试
GD32E10x官方例程入门:从GPIO点灯到串口调试

简介:这份GD32E10x系列官方例程面向嵌入式硬件与单片机开发者,基于ARM Cortex-M3内核,汇集兆易创新GD32E10x的示例代码,适合工业控制、消费电子、通信设备等场景的学习、验证与二次开发。压缩包共935个文件,约11.16MB&… · 2026/11/5 13:52:29

基于Django的运维平台实战:资产、发布、巡检、告警一体化
基于Django的运维平台实战:资产、发布、巡检、告警一体化

简介:这份资源是一套基于Django框架开发的运维平台源码,面向具备Python基础、希望了解Web运维系统实现思路的开发者与运维人员,可用于学习主机管理、服务监控、日志查看、任务调度、权限控制、资源统计、脚本执行与故障告警等常见运维模块的落… · 2026/11/5 13:49:27

基于ADS122U04IPWR与STM32F427ZI的工业测温方案设计
基于ADS122U04IPWR与STM32F427ZI的工业测温方案设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 13:22:54

SSM超市管理系统实战:从课设跑通到二次开发全解析
SSM超市管理系统实战:从课设跑通到二次开发全解析

简介:这份资源是面向高校计算机相关专业学生与Java入门开发者的SSM课程设计参考项目,围绕超市管理场景,解决商品、库存、销售等业务模块从设计到落地的实践需求,适合作为课程作业、毕业设计原型或SSM框架练手案例。压缩包共792个文… · 2026/11/5 13:18:49

SSM超市管理系统源码解析:从分层架构到本地部署与业务修改
SSM超市管理系统源码解析:从分层架构到本地部署与业务修改

简介:这份资源是面向高校计算机专业学生与Java初学者的一套SSM框架课程设计完整项目,围绕超市管理场景,帮助读者完成从框架整合到业务模块落地的实战练习,适合作为毕业设计或课程作业的参考方案。压缩包共792个文件,约… · 2026/11/5 13:17:48

Dubbo服务下线实时告警:基于ZooKeeper Watch的轻量级监控方案
Dubbo服务下线实时告警:基于ZooKeeper Watch的轻量级监控方案

简介:这是一套面向Java分布式系统运维与开发人员的Dubbo服务高可用监控解决方案,聚焦于Provider异常下线的实时感知与告警响应。资源通过Zookeeper监听机制实现服务状态变更捕获,结合邮件通知模块,在不侵入原有Dubbo代码的前提下&… · 2026/11/5 13:15:46

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07

多智能体协作系统架构设计与实践优化
多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中… · 2026/11/5 0:00:39

大模型系统性入门实战指南:从原理到部署微调的全链路路线
大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#… · 2026/11/5 0:00:39

鸿蒙文件系统沙箱机制解析与开发实践
鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的… · 2026/11/5 0:00:39

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:27:59

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:03

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/5 10:28:07

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码