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

大话计算机网络(上)

一、TCP和UDP的区别:

1. 连接方式

  • TCP(Transmission Control Protocol,传输控制协议)
    面向连接,传输前必须先建立连接(三次握手),通信结束后要断开连接(四次挥手)。
  • UDP(User Datagram Protocol,用户数据报协议)
    无连接,直接发数据,不需要建立或断开连接。

2. 可靠性

  • TCP

    • 提供可靠传输:有确认机制、重传机制、流量控制、拥塞控制。
    • 能保证数据 不丢失、不重复、按顺序到达
  • UDP

    • 不保证可靠性:没有确认和重传机制。
    • 可能丢包、乱序。

3. 传输效率

  • TCP

    • 开销大(需要建立连接、维护状态、做校验、重传等)。
    • 传输效率相对较低。
  • UDP

    • 头部开销小(8 字节,对比 TCP 的 20 字节起步)。
    • 传输效率高,延迟低。

4. 应用场景

  • TCP 适合可靠传输场景
    如:HTTP/HTTPS、FTP、SMTP、数据库连接。
    (需要保证数据完整性和顺序性)

  • UDP 适合实时场景
    如:视频直播、语音通话、在线游戏、DNS 查询。
    (容忍少量丢包,但需要低延迟)


一句话

  • TCP = 慢但可靠(适合“文件传输”类)
  • UDP = 快但不可靠(适合“实时传输”类)

实例代码:

TCP:
TCP服务端:

import java.io.*;
import java.net.*;public class TcpServer {public static void main(String[] args) throws IOException {ServerSocket serverSocket = new ServerSocket(6666); // 监听端口System.out.println("TCP 服务端启动,等待连接...");Socket socket = serverSocket.accept(); // 阻塞等待客户端连接System.out.println("客户端已连接: " + socket.getInetAddress());BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out = new PrintWriter(socket.getOutputStream(), true);String msg = in.readLine();System.out.println("收到客户端消息: " + msg);out.println("服务端回复: 已收到 -> " + msg);socket.close();serverSocket.close();}
}

TCP客户端:

import java.io.*;
import java.net.*;public class TcpClient {public static void main(String[] args) throws IOException {Socket socket = new Socket("localhost", 6666); // 连接服务端PrintWriter out = new PrintWriter(socket.getOutputStream(), true);BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));out.println("Hello TCP!"); // 发送消息String reply = in.readLine(); // 接收回复System.out.println("收到服务端回复: " + reply);socket.close();}
}

运行效果:
1、先启动TcpServer,它会阻塞等待连接
2、再运行TcpServer,服务端会打印受到的消息,并回复客户端

UDP示例
UDP服务端:

import java.net.*;public class UdpServer {public static void main(String[] args) throws Exception {DatagramSocket socket = new DatagramSocket(8888); // 监听端口byte[] buf = new byte[1024];System.out.println("UDP 服务端启动,等待数据...");DatagramPacket packet = new DatagramPacket(buf, buf.length);socket.receive(packet); // 阻塞等待数据String msg = new String(packet.getData(), 0, packet.getLength());System.out.println("收到客户端消息: " + msg);// 回复消息String reply = "服务端收到 -> " + msg;byte[] data = reply.getBytes();DatagramPacket replyPacket = new DatagramPacket(data, data.length, packet.getAddress(), packet.getPort());socket.send(replyPacket);socket.close();}
}

UDP客户端:

import java.net.*;public class UdpClient {public static void main(String[] args) throws Exception {DatagramSocket socket = new DatagramSocket();String msg = "Hello UDP!";byte[] data = msg.getBytes();InetAddress address = InetAddress.getByName("localhost");DatagramPacket packet = new DatagramPacket(data, data.length, address, 8888);socket.send(packet); // 发送消息// 接收服务端回复byte[] buf = new byte[1024];DatagramPacket replyPacket = new DatagramPacket(buf, buf.length);socket.receive(replyPacket);String reply = new String(replyPacket.getData(), 0, replyPacket.getLength());System.out.println("收到服务端回复: " + reply);socket.close();}
}

二、TCP三次握手

在这里插入图片描述

1. 为什么需要三次握手?

TCP 是面向连接的、可靠的协议,建立连接前要确保 双方都具备收发能力

  • 一次握手:只能确认 客户端 → 服务端 的发送没问题。
  • 两次握手:只能确认 双向传输通路,但不能防止 旧连接请求 造成混乱。
  • 三次握手:既能确认收发能力,也能避免历史报文影响,最终保证连接可靠。

2. 三次握手过程

假设:客户端 (Client),服务端 (Server)。

第一次握手

  • Client → Server
  • Client 发送 SYN = 1,选择一个初始序列号 Seq = x
  • 表示:“我要建立连接,这是我的起始序号。”

第二次握手

  • Server → Client
  • Server 收到请求后,回复 SYN = 1, ACK = 1,确认号 Ack = x + 1,并生成自己的初始序列号 Seq = y
  • 表示:“我收到了你的请求,也要建立连接,这是我的起始序号。”

第三次握手

  • Client → Server
  • Client 收到回复后,再发 ACK = 1,确认号 Ack = y + 1,序号 Seq = x + 1
  • 表示:“我确认收到你的序号,连接可以正式建立。”

此时,双方连接建立成功,进入 ESTABLISHED 状态,可以开始传输数据。

  • 三次握手保证了 双方序列号的同步
  • 避免了 历史连接请求报文 导致的错误连接。
  • 握手完成后,通信双方进入 全双工通信(可以同时收发)。

一句话总结
TCP 三次握手是 确保客户端和服务端都有收发能力、并且序列号同步的过程,是可靠传输的前提。

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

相关文章:

  • JVM方法调用机制深度解析:从aload_1到invokevirtual的完整旅程
  • STM32CubeIDE学习——安装
  • 追觅宣布进军手机市场,已经白热化的手机赛道追觅优势何在?
  • AI智能体开发工作流的成功案例分享及思路
  • 【算法基础】String、Hash 与 Stack
  • 使用springboot开发一个宿舍管理系统练习项目
  • 像素版推箱子游戏
  • 2025年CSP-J认证 普及组初赛真题解析 CCF信息学奥赛C++ 中小学初级组 第一轮真题-选择题解析
  • 【精品资料鉴赏】121页可编辑PPT详解医药集团合规管控规划方案
  • Linux用户权限与进程管理深度解析
  • [数据结构] 反射,枚举与lambda表达式
  • 奇异值:数据科学的数学基石与应用核心
  • Python 2025:安全编程与漏洞防范实战指南
  • ​​[硬件电路-286]:高速轨到轨比较器TLV3603DCKR 功能概述与管脚定义
  • CAR 细胞疗法:破解自身免疫性疾病的 “免疫纠错” 新路径
  • FreeRTOS实战指南 — 5 多任务系统实现流程
  • `css`使单词保持连贯的两种方法
  • 【Vue3 ✨】Vue3 入门之旅 · 第三篇:模板语法与数据绑定
  • 分类预测 | Matlab实现PCA-BP主成分分析结合BP神经网络多特征分类预测
  • 【Linux】进程优先级切换调度
  • Ubuntu24上安装Scrapy框架实战
  • 正向shell,反弹shell学习
  • 一维数组原地更新——力扣119.杨辉三角形II
  • Python语法学习-1
  • Linux基础命令大全
  • 9.21 快速选择
  • 【常见集合】HashMap
  • Docker安装小白教程(阿里yum)
  • MySQL表结构变更详解:ALTER TABLE ADD COLUMN语法、最佳实践与避坑指南
  • 【LeetCode - 每日1题】设计电子表格