网络学习-TCP协议(七)
一、TCP协议
TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
1、三次握手
客户端:
1、先发起连接,发送SYN置1,seqnum=12345(随机值)----半连接建立,形成syn队列
服务端:
1、收到SYN,分配tcp控制块
2、发送ack置1,acknum=12346, syn,seqnum=34531(随机值)
客户端:
2、发送ack,acknum=34532 ,seqnum=12346(从之前的序列号+1) ----半连接转为全连接,进入accept队列
小结:
可见在TCP协议中,服务端是被动连接。
2、四次挥手
注意只有主动方和被动方:
1、主动发起断开连接,发送FIN置1,seqnum=1234(随机值)
2、被动方收到FIN,发送ack置1,acknum=1235(seq+1)
3、被动方发送FIN,seqnum=5678(随机值)
4、主动方收到FIN,发送ack置1,acknum=5679(seq+1)
3、TCP的格式
首部开销最小20字节,最大60字节
4、网络协议栈
应用层:http,ftp,ssh
传输层:TCP,UDP
网络层:IP,ICMP
5、TCP发生在哪些函数中:
通过对网络I/O的学习,发现无论使用select,poll,还是epoll,都没看见TCP/UDP的相关字眼,那电脑是如何判断使用哪种协议来实现连接的?
回顾之前代码,主要使用了socket(),bind(), listen(), accept(), connect(), send(), recv(), **close()**这几个函数。
- 这些函数是如何实现TCP连接的?
- 这些函数编译生成的执行文件,为什么在不同系统平台可以正常运行?
二、POSIX API
1、什么是POSIX API?
- 是一套可移植操作系统接口标准,旨在使应用程序可以在多种UNIX和类UNIX操作系统上运行而无需修改。
- 像之前使用的socket(),bind(), listen(), accept(), connect(), send(), recv(), close(),fcntl(),select,poll,epoll等函数,都是POSIX API的一部分。
2、三次握手的过程,发送在哪些函数里面:
-
客户端:
client:
Connet() -
server:
listen();
accept();
3、API简介
1. socket()
int socket(int domain, int type, int protocol);
/*
*socket英文单词的本意是插座,在网络编程中,socket代表网络IO的建立,实质是(fd,tcp控制块--stream)
*功能:
*分配fd,bitmap
*tcp控制块的分配
*domain:通信协议族,AF_INET, AF_UNIX,AF_INET6,大部分都是基于IPV4的网络通信,通常使用AF_INET
*type:指定套接字类型,SOCK_STREAM(字节流)---TCP协议,SOCK_DGRAM(报文)---UDP协议,SOCK_RAW---原始套接字
*protocol:指定具体的协议,通常为0。前两个参数确定了,第三个参数通常为0,由内核自动选择合适的协议
*返回值:成功返回非负文件描述符,失败返回-1
*/
2. bind()
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
/*
1、绑定固定ip,port
2、还未到tcp建立过程
3、属于设置过程
返回值:成功返回0,失败返回-1
*/
3. listen()
int listen(int sockfd, int backlog);
/*
1、设置监听,等待客户端连接
2、backlog:半连接队列的大小(内核参数,默认值5)
3、TCP开始建立
返回值:成功返回0,失败返回-1
实质:
1、把TCP的status设置为TCP_STATUS_LISTEN
2、如果不设置,强行连接,会被拒绝
3、设置tcp全连接队列和半连接队列tcp->syn_queuetcp->accept_queue
*/
4. accept()
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
/*
1、阻塞等待客户端的连接请求
2、属于建立TCP的完成后
返回值:成功返回非负文件描述符,失败返回-1
实质:
分配fd给客户端,并把客户端的fd和tcp控制块绑定EPOLLLT:水平触发
只要有事件就绪就会一直通知EPOLLET:边缘触发
只有当事件发生时才会通知一次
避免不能及时响应需要额外添加while循环进行处理
while(1){fd = accept(listenfd, NULL, NULL);if(fd < 0) {break;}
}
*/
5. connect()
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
/*
1、主动发起tcp连接
2、属于建立TCP的过程
返回值:成功返回0,失败返回-1
*/
6. send()
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
/*
flags:用于指定发送数据的特殊选项,如MSG_DONTWAIT,非阻塞模式,一般默认为0
1、发送数据到对方
2、属于传输层
返回值:成功返回发送的字节数,失败返回-1
实质:
将数据从用户空间拷贝到内核缓冲区,然后通过网络发送到对方的内核缓冲区(协议栈),异步操作
*/ssize_t write(int fd, const void *buf, size_t count);
/*
1、发送数据到对方
返回值:成功返回发送的字节数,失败返回-1
相比于send,少了一个flags参数,其余相同,send是POSIX API,write是标准C库函数
如果是网络编程,推荐使用send,因为send可以指定flags参数
*/
7. recv()
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
/*
flags:用于指定接收数据的特殊选项,如MSG_WAITALL,阻塞直到所有数据都收到
1、接收数据
2、属于传输层
返回值:成功返回接收的字节数,失败返回-1
实质:
将对方内核缓冲区的数据拷贝到用户空间缓冲区,异步操作
*/
ssize_t read(int fd, void *buf, size_t count);
/*
1、接收数据
返回值:成功返回接收的字节数,失败返回-1
相比于recv,少了一个flags参数,其余相同,recv是POSIX API,read是标准C库函数
如果是网络编程,推荐使用recv,因为recv可以指定flags参数
*/
8. close()
int close(int fd);
/*
1、关闭fd,释放bitmap位图资源
2、如果是TCP连接,会发送fin包给对方,等待对方的ack包
3、如果是UDP连接,直接释放资源
返回值:成功返回0,失败返回-1
实质:
回收fd,释放bitmap位图资源
如果是tcp连接,发送fin包给对方,等待对方的ack包
如果是udp连接,直接释放资源
*/int shutdown(int sockfd, int howto);
/*
howto:用于指定关闭哪一部分连接,SHUT_RD(关闭读),SHUT_WR(关闭写),SHUT_RDWR(同时关闭读写)
1、关闭fd,释放bitmap位图资源
2、如果是TCP连接,可以指定只关闭读或者写
返回值:成功返回0,失败返回-1
实质:
回收fd,释放bitmap位图资源
如果是tcp连接,可以选择只关闭读或者写
不推荐使用,关闭连接就关闭了,使用shutdown,还只关闭一部分连接,容易引起混乱
*/
三、总结
1、在TCP传输过程中,服务端属于被动连接,客户端属于主动发起连接。
2、对于不同的系统平台,使用了POSIX API,可以实现跨平台网络编程。
四、拓展问题
1、tcp连接的生命周期从什么时候开始?
tcp连接的生命周期是从三次握手开始,到四次挥手结束。即客户端调用connect()开始,到服务端调用close()结束。
2、第三次握手数据包,如何从半连接队列查找匹配的节点
源端口,目的端口,源ip,目的ip
3、syn泛洪攻击
- 定义:
syn泛洪攻击是一种常见的网络攻击手段,其目的是通过发送大量的TCP连接请求(SYN包),耗尽服务器的资源,从而阻止合法的用户建立正常的TCP连接。 - 解决方案:
早期系统版本,通过listen(fd, backlog)第二个参数,控制半连接队列的大小
然后是将半连接队列的大小设置为syn+accept队列总长度,放未分配fd的tcb的数量
现在大部分系统是将半连接队列的大小设置为accept队列长度
4、为什么建立连接需要三次握手,而断开连接需要四次挥手?
- 三次握手:
为了实现数据的可靠性传输;TCP通信协议双方,都必须维护一个序列号,以标识发送出去的数据包,哪些是已经被对方收到。实质上是通信双方相互告知序列号的起始值,并确认对方已经收到了这个序列号。如果是两次握手,至多只有连接发起方的序列号能被确认,而另一方的序列号无法被确认。 - 四次挥手:
为了保证数据完整性,TCP协议需要通过四次挥手来正确关闭连接。主动方发送FIN包后,被动方需要先回复ACK确认收到,然后再发送自己的FIN包给主动方,最后等待主动方的ACK确认收到后才真正断开连接。这样可以确保双方都能够正确地关闭连接,避免数据丢失
5、accept发生在三次握手的哪一步
发生在第三次握手之后,TCP建立完成之后。
6、TCP是如何保证顺序的?
通过序列号、确认应答、重传机制、滑动窗口和拥塞控制等多种机制来保证数据的顺序性。
7、ack没有收到,先收到fin怎么办?
继续发ack
8、双方调用close会发生什么?
结论:服务端会出现大量的TIME_WAIT状态
- 双方发送FIN报文,都进入FIN_WAIT_1状态
- 双方收到FIN并发送ACK,都进入closing状态
- 双方收到ACK并进入TIME_WAIT状态,等待2MSL(最大段生存时间)以确保对方收到ACK。
- 连接完全关闭,2MSL超时后,双方都进入CLOSED状态,连接完全关闭。
相关文章:

网络学习-TCP协议(七)
一、TCP协议 TCP(Transmission Control Protocol,传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。 1、三次握手 客户端: 1、先发起连接,发送SYN置1,seqnum12345(随机值)----半连接…...

基于微信小程序的高校校园微活动管理系统设计与实现(源码+定制+开发)高校微信小程序校园活动发布与互动平台开发 面向大学生群体的校园活动移动平台设计与实现
博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…...
Python 项目中安装 OpenAI 库的详细指南
在 Windows 系统中指定版本安装 OpenAI 库的指南 在 Windows 系统中,尤其是使用 Python 3.7.8 时,安装 OpenAI 库可能会遇到一些问题。本文将为你提供一个简单易懂的解决方案,帮助你成功安装指定版本的 OpenAI 库。 一、问题背景 当你在 W…...

云计算与大数据进阶 | 27、存储系统如何突破容量天花板?可扩展架构的核心技术与实践—— 分布式、弹性扩展、高可用的底层逻辑(上)
数据中心里,存储系统是至关重要的组成部分。由于相关硬件组件与存储操作系统的多样性和复杂性,如何在保证存储稳定、安全、可靠的同时,实现灵活扩展和自服务,一直是困扰数据中心全面云化的难题。 简单来说,现在的难题…...
使用Gemini, LangChain, Gradio打造一个书籍推荐系统 (第二部分)
建立向量嵌入数据库 from langchain_community.document_loaders import TextLoader from langchain_text_splitters import CharacterTextSplitter from langchain.docstore.document import Document from langchain_chroma.vectorstores import Chromaimport vertexai from…...

IvorySQL-WASM:免安装的数据库探索之旅
简介 为了降低社区用户的使用门槛,提升使用体验,IvorySQL 社区特别推出了 IvorySQL-WASM 项目,帮助用户快速在线 Demo。 IvorySQL-WASM 基于开源的 Postgres-WASM 框架开发。它允许用户直接在网页浏览器中体验 IvorySQL,无需本地…...

飞牛fnNAS远程映射盘符
目录 一、NAS、PC端配置Zerotier 二、使用网上邻居 三、使用WebDAV 1.开启WebDAV 2.PC上安装RaiDrive并设置 如果能将NAS作为本机一个盘符来使用,一定会令我非常方便。如果是本地,可以很方便实现。 将飞牛NAS映射为本地盘符,常用两种方式,一种是网上邻居,另一种是We…...

Java设计模式:探索编程背后的哲学
设计模式是软件开发中的一种常见方法,它为常见问题提供了解决方案。在Java世界中,设计模式的应用尤为广泛。本文将深入探讨Java设计模式的起源、分类和实际应用,帮助读者更好地理解和应用这些模式。设计模式不仅是编程的技术,更是…...
会话管理有哪些
使用服务器或者框架的会话管理控制。应用程序应当只识别有效的会话标识符。 会话标识符必须总是在一个可信系统(比如:服务器)上创建。 会话管理控制应当使用通过审查的算法以保证足够的随机会话标识符。 为包含已验证的会…...
《C++20新特性全解析:模块、协程与概念(Concepts)》
引言:C20——现代C的里程碑 C20是继C11之后最具革命性的版本,它通过模块(Modules)、协程(Coroutines)和概念(Concepts)三大核心特性,彻底改变了C的代码组织方式、并发模…...

Docker部署OpenSearch集群
OpenSearch 简介 OpenSearch 是一款开源的搜索与分析引擎,最初由亚马逊 AWS 开发,于 2021 年 9 月将其移交至 Linux 基金会旗下的 OpenSearch 软件基金会,此后实现了社区主导的治理模式。其具有高性能、可扩展性强、兼容性强等优点ÿ…...
三宽用到的网络类型
用家宽、企宽和专线运行P2P的网络类型本质要求一致,但具体配置和优化方向因宽带类型而异。以下是关键差异与共性分析: 一、核心网络类型要求(三者的共性) 公网IP 必要性:均需公网IP(非内网IP)以…...

【AS32X601驱动系列教程】PLIC_中断应用详解
平台中断控制器(Platform Level Interrupt Controller,PLIC)是国科安芯AS32系列MCU芯片的中断控制器,主要对中断源进行采样,优先级仲裁和分发。各外设中断统一连到PLIC,PLIC统一管理并输出中断请求到内核。…...
单目视觉测量及双目视觉测量
一、单目视觉测量 1.1 原理部分讲解 单目视觉系统通过采集图像,将图像转换为二维数据,然后对采集的图像进行模式识别,通过图像匹配算法识别行驶过程中的车辆、行人、交通标志等,最后依据目标物体的运动模式和定位…...

python学习打卡day34
DAY 34 GPU训练及类的call方法 知识点回归: CPU性能的查看:看架构代际、核心数、线程数GPU性能的查看:看显存、看级别、看架构代际GPU训练的方法:数据和模型移动到GPU device上类的call方法:为什么定义前向传播时可以直…...
掩码与网关是什么?
1. 子网掩码(Subnet Mask) 作用:划分“小区”范围 想象你住在一个小区(子网)里: 小区门牌号 IP地址(如 192.168.1.10) 小区边界 子网掩码(如 255.255.255.0…...

leetcode-快慢指针系列
开胃小菜 141. 环形链表 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链…...

JAVA05基本数据类型和包装类的转换,转换成其他数据类型,包装类与字符串的转换+学生类的定义实例
1.基本数据类型和包装类的转换 下面是一个自动手动的例题 2.将包装类转换成其他类型 3. 将数据类型转换成字符串 将字符串转换成数据类型 以下是一个例题 学生类的例题...

Python打卡训练营学习记录Day34
知识点回归: CPU性能的查看:看架构代际、核心数、线程数 GPU性能的查看:看显存、看级别、看架构代际 GPU训练的方法:数据和模型移动到GPU device上 类的call方法:为什么定义前向传播时可以直接写作self.fc1(x) CPU性…...

动手学习深度学习V1.1 chapter2 (2.1-2.2)
chapter2:深度学习基础 区分问题:回归问题还是分类问题? 输出结果是不明确的连续值的时候就是回归问题,比如房价预测,销售额预测等。 输出结果是明确几个离散值的时候就是分类问题,比如字符识别…...

数据结构(6)线性表-队列
一、队列的概述 队列也是一种特殊的线性表,只允许在一段插入数据,另一端删除数据。插入操作的一端称为队尾,删除操作的一端称为队头。 如图: 二、队列相关操作 1.队列结构体的声明 类似于栈,他肯定也得借助于数组或…...
NumPy 2.x 完全指南【十七】转置操作
文章目录 1. 什么是转置2. 转置操作2.1 transpose2.2 ndarray.T2.3 moveaxis2.4 rollaxis2.5 permute_dims2.6 swapaxes2.7 matrix_transpose 1. 什么是转置 在线性代数中,矩阵转置是指将矩阵的行和列进行互换,即原矩阵的第 i i i 行、第 j j j 列元素…...

【数据架构04】数据湖架构篇
✅ 10张高质量数据治理架构图 无论你是数据架构师、治理专家,还是数字化转型负责人,这份资料库都能为你提供体系化参考,高效解决“架构设计难、流程不清、平台搭建慢”的痛点! 🌟限时推荐,速速收藏&#…...
使用OpenSSL生成根证书并自签署证书
生成根CA的私钥和证书 # 生成根 CA 的私钥 [rootdeveloper ssl]# openssl genrsa -out rootCA.key 2048 Generating RSA private key, 2048 bit long modulus (2 primes) ... ............................................................ e is 65537 (0x010001)# 使用私钥生…...

uniapp-商城-62-后台 商品列表(分类展示商品的布局)
每一个商品都有类别,比如水果,蔬菜,肉,粮油等等,另外每一个商品都有自己的属性,这些都在前面的章节进行了大量篇幅的介绍。这里我们终于完成了商品类的添加,商品的添加,现在到了该进…...

初识C++:模版
本篇博客主要讲解C模版的相关内容。 目录 1.泛型编程 2.函数模板 2.1 函数模版概念 2.2 函数模版格式 2.3 函数模版的原理 2.4 函数模版的实例化 1.隐式实例化:让编译器根据实参推演模板参数的实际类型 2. 显式实例化:在函数名后的<>中指定模…...
【Elasticsearch】给所索引创建多个别名
Elasticsearch 是可以给索引创建多个别名的。 为什么可以创建多个别名 1. 灵活性 - 别名可以为索引提供一个更易于理解的名称,方便用户根据不同的业务场景或用途来引用同一个索引。例如,一个索引可能同时服务于多个不同的应用程序或服务,通…...
Linux入门(九)任务调度
设置任务调度文件 /etc/crontab #设置调度任务 crontab -e #将任务设置到调度文件 # * * * * * # 第1个* 分钟 0-59 # 第2个* 小时 0-23 # 第3个* 天 1-31 # 第4个* 月 1-12 # 第5个* 周 0-7 0和7都代表的是星期天 #每分钟执行 */1 * * * * ls -l /etc/ > /tmp/to.txt0 8,…...

突破认知边界:神经符号AI的未来与元认知挑战
目录 一、神经符号AI的核心领域与研究方法 (一)知识表示:构建智能世界的语言 (二)学习与推理:让机器“思考”与“学习” (三)可解释性与可信度:让AI更透明 …...

Java 处理地理信息数据[DEM TIF文件数据获取高程]
目录 1、导入依赖包 2、读取方法 3、其他相关地理信息相关内容: 1️⃣常用的坐标系 1、GIS 中的坐标系一般分为两大类: 2. ✅常见的地理坐标系 2.0 CGCS2000(EPSG:4490) 2.1 WGS84 (World Geodetic System 1984) (EPSG…...