网络原理之TCP/IP

本文深入探讨了TCP协议的工作原理,包括其可靠性机制如确认应答、超时重传和连接管理(三次握手、四次挥手)。通过实例展示了TCP如何确保数据的有序、无错传输,并与UDP进行对比。同时,介绍了网络分层模型以及TCP在传输层的角色,解释了TCP如何根据接收方能力和网络状况进行流量控制。
摘要由CSDN通过智能技术生成

发送: 封装 接受:解包+分用

封装:OS的代码进行封装

2观察封装后的数据(抓包工具——wireshark)

端口只能绑定到一个进程上

目录

传输层TCP协议:进程TO进程 +可靠性

网络分层

请求——响应模式

TCP 和UDP的区别

TCP协议段格式

 TCP原理

确认应答机制

超时重传机制

连接管理机制:TCP三次握手四次挥手

使用TCP协议

传输层TCP协议:进程TO进程 +可靠性

什么是可靠性??

比起UDP

当数据没有发送出去时 TCP会告诉进程数据发送失败了

保证不会收到错误的数据(通过checksum)

TCP能够保证收到的数据一定是有序的(按照发送进程发送时的顺序)

TCP根据对方接受的能力和网络线路的承载能力 流量控制

TCP通过哪些机制来保证可靠性的

确认应答机制(数据编号机制+超时重传机制) 接收方(对方的TCP)有责任对收到的数据进行确认应答

给数据进行编号 编号放在TCP协议段的32位序号中

包头 segment sn ack ASN等信息就保证了可靠性

比起UDP TCP有了缓冲区

1在数据发送之后数据并没有被直接丢弃 而是被保存了下来 保存在缓存区

2TCP也有一个接受缓冲区

3 TCP得维护发送或接受时的序号 可以得到去重的效果

网络分层

发送数据报时,发送端主机都需要先根据网络分层从上到下封装:

层次主要职责重点协议相关概念
应用层处理业务逻辑HTTP(S) DNS请求/响应
传输层跨主机 进程TO进程TCP UDP段/报文/端口
网络层跨LAN 主机TO主机IP包/IP地址
数据链路层LAN内 主机TO主机帧/MAC地址
应用层:应用程序基于HTTP协议的封装
传输层:操作系统基于TCP协议的封装
网络层:操作系统基于IP协议的封装
数据链路层:操作系统基于以太网帧封装

源主机和目的主机在同一个网段时,下一跳设备就是目的主机;
发送端主机和接收端主机在不同网段时,发送端主机是无法知道目的主机在哪,此时会设置下一跳
设备为网关设备;也就是当跨LAN时 数据就会经过很多路由器接力传到目的主机

跨机请求下:

请求——响应模式

1同一个主机下进程(Server)TO进程(Client)

package hututu.about_join.tcp;

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Scanner;

// UDP: 无连接       写信
// TCP: 有连接       打电话
public class Server {
    private static final HashMap<String, String> map = new HashMap<>();
    static {
        map.put("apple", "苹果");
        map.put("banana", "香蕉");
    }

    public static void main(String[] args) throws IOException {
        // 1. 开店(创建 socket)
        Login.println("服务器启动,监听在 TCP:8079 端口");
        ServerSocket serverSocket = new ServerSocket(8079);
        // 进行循环
        while (true) {
            // 1. 接通连接(电话) —— accept
            Login.println("等待新的客户端连接上来");
            Socket socket = serverSocket.accept();  // 阻塞
            Login.println("有新的客户端连接上来");

            InetAddress inetAddress = socket.getInetAddress();
            Login.println("对方的地址: " + inetAddress);
            int port = socket.getPort();
            Login.println("对方的端口: " + port);

            // is: 用于读数据
            InputStream is = socket.getInputStream();
            // os: 用于写数据
            OutputStream os = socket.getOutputStream();

            // 2. 读取请求
            Scanner scanner = new Scanner(is, "UTF-8");
            String header = scanner.nextLine(); // "我是 Java19班的"
            // TODO: 做请求格式检查
            String englishWord = scanner.nextLine();
            Login.println("英文单词: "+ englishWord);

            // 3. 处理业务
            String chineseWord = map.getOrDefault(englishWord, "不认识");
            Login.println("中文单词: "+ chineseWord);

            // 4. 发送响应
            // 好的\r\n苹果\r\n
            // OutputStream -> OutputStreamWriter -> PrintWriter
            OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8");
            PrintWriter printWriter = new PrintWriter(writer);

            Login.println("服务器进行发送");
            printWriter.printf("好的\r\n%s\r\n", chineseWord);
            printWriter.flush();    // 不要忘记 flush
            Login.println("服务器发送成功");

            socket.close();
        }
    }
}
package hututu.about_join.tcp;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 8079);

        InputStream is = socket.getInputStream();
        Scanner scanner = new Scanner(is, "UTF-8");

        OutputStream os = socket.getOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8");
        PrintWriter printWriter = new PrintWriter(writer);

        // 发送请求
        printWriter.printf("我是Java19班的\r\napple\r\n");
        printWriter.flush();

        // 读取响应
        String header = scanner.nextLine(); // 好的
        String word = scanner.nextLine();   // 苹果
        System.out.println(word);

        socket.close();
    }
}

跨主机

可以把server设置在LINUX云服务器上服务器   client运行在自己电脑上

TCP 和UDP的区别

TCPUDP
面向字节流(可能累计数据一起发送)面向数据报文(有了数据 立即发送)
可靠 不可靠 无连接
(失败会有响应 按进程顺序发送 根据对方接受能力网络线路的承载能力 流量控制)(只能保证数据发送了 不能保证数据有没有接收到)

TCP协议段格式

源/目的端口号:表示数据是从哪个进程来,到哪个进程去;
32位序号/32位确认号:
4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节);所以TCP头部最大长度是15 * 4 = 60
6位标志位:
URG:紧急指针是否有效
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接;我们把携带RST标识的称为复位报文段
SYN:请求建立连接;我们把携带SYN标识的称为同步报文段
FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
16位窗口大小:后面再说
16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光
包含TCP首部,也包含TCP数据部分。
16位紧急指针:标识哪部分数据是紧急数据;
40字节头部选项:暂时忽略;

 TCP原理

 TCP对数据传输提供的管控机制,主要体现在两个方面:安全和效率。
这些机制和多线程的设计原则类似:保证数据传输安全的前提下,尽可能的提高传输效率。

确认应答机制

TCP将每个字节的数据都进行了编号 ——序列号

每一个ACK都有对应的序列号 意思就是告诉发送者我收到了哪些数据

超时重传机制

 所以当B收到这些重复数据 TCP就会识别序列号 然后达到去重的效果

连接管理机制:TCP三次握手四次挥手


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是香橙啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值