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

TCP通信流程以及一些TCP的相关概念

1.TCP和UDP区别

都为传输层协议
UDP:用户数据报协议,面向无连接,可以单播,多播,广播,面向数据报,不可靠
TCP:传输控制协议,面向连接的,可靠的,基于字节流,仅支持单播传输

UDPTCP
是否创建连接无连接面向连接
是否可靠不可靠可靠的
连接的对象个数一对一、一对多、多对一、多对多一对一
传输的方式面向数据报面向字节流
首部开销8个字节最少20个字节
适用场景实时应用(视频会议,直播)可靠性高的应用

2.TCP通信流程

(1) 服务器端
1.创建一个用于监听的套接字
      -监听:监听有客户端的连接
      -套接字:就是一个文件描述符
2.将这个监听文件描述符和本地的IP和端口绑定(IP和端口就是服务器的地址信息)
      -客户端连接服务器的时候使用的就是这个IP和端口
3.设置监听,监听的fd开始工作
4.阻塞等待,当有客户端发起连接,解除阻塞,接受客户端的连接,会得到一个和客户端通信的套接字(fd)
5.通信
      -接收数据
      -发送数据
6.通信结束,断开连接

(2) 客户端
1.创建一个用于通信的套接字(fd)
2.连接服务器,需要指定连接的服务器的IP和端口3.连接成功了,客户端可以直接和服务器通信
      -接收数据
      -发送数据
4.通信结束,断开连接

3.通信时所需要用到的函数(API)

int socket(int domain,int type,int protoco1);-功能:创建一个套接字-参数:- domain : 协议族AF_INET : ipv4 AF_INET6 : ipv6AF__UNIX,AF_LOCAL :本地套接字通信(进程间通信>- type : 通信过程中使用的协议类型SOCK_STREAM ︰流式协议SOCK_DGRAM︰报式协议-protoco1 : 具体的一个协议。一般写0- SOCK_STREAM︰流式协议默认使用 TCP- SOCK_DGRAM︰报式协议默认使用UDP-返回值:-成功:返回文件描述符,操作的就是内核缓冲区。-失败:-1int bind(int sockfd,const struct sockaddr *addr,socklen_t addr len);-功能:绑定,将fd 和本地的IP +端口进行绑定-参数:- sockfd :通过socketi函数得到的文件描述符- addr :需要绑定的socket地址,这个地址封装了ip和端口号的信息- addrlen :第二个参数结构体占的内存大小int listen(int sockfd,int backlog);  // /proc/sys/net/core/somaxconn-功能:监听这个socket上的连接-参数:- sockfd :通过socket()函数得到的文件描述符- backlog :未连接的和已经连接的和的最大值,5int accept(int sockfd,struct sockaddr *addr ,socklen_t *addrlen);-功能:接收客户端连接,默认是一个阻塞的函数,阻塞等待客户端连接-参数:- sockfd :用于监听的文件描述符- addr :传出参数,记录了连接成功后客户端的地址信息(ip, port)- addrlen :指定第二个参数的对应的内存大小-返回值:-成功:用于通信的文件描述符- -1 :失败
int connect(int sockfd,const struct sockaddr *addr, socklen_t addrlen) ;-功能:客户端连接服务器-参数:- sockfd :用于通信的文件描述符- addr :客户端要连接的服务器的地址信息- addrlen :第二个参数的内存大小-返回值: 成功0,失败-1
ssize_t write(int fd,const void *buf,size_t count);//写数据
ssize_t read(int fd,void *buf, size_t count);//读数据

4.TCP三次握手

目的:保证双方互相之间建立了连接
什么时候三次握手:发生在客户端连接时
为甚莫要三次握手:确认双方都能发送和接收数据
三次握手在TCP协议头中1.将SYN的值置为12.服务端将ACK置为1,并且将SYN置为13.客户端将ACK置为1
序号,确认号:确保TCP协议的传输时的完整性和顺序性

第一次握手:1.客户端将SYN标志位置为12.生成一个随机的32位的序号seq=J ,这个序号后边是可以携带数据(数据的大小)
第二次握手:1.服务器端接收客户端的连接:ACK=12.服务器会回发一个确认序号:ack=客户端的序号+数据长度+SYN/FIN(按一个字节算)3.服务器端会向客户端发起连接请求:SYN=14.服务器会生成一个随机序号:seq = K
第三次握手:1.客户单应答服务器的连接请求:ACK=12.客户端回复收到了服务器端的数据:ack=服务端的序号+数据长度+SYN/FIN(按一个字节算)

5.三次握手、滑动窗口、四次挥手

# mss: Maximum Segment Size(一条数据的最大的数据量)
# win: 滑动窗口
1. 客户端向服务器发起连接,客户单的滑动窗口是4096,一次发送的最大数据量是1460
2. 服务器接收连接情况,告诉客户端服务器的窗口大小是6144,一次发送的最大数据量是1024
3. 第三次握手
4. 4-9 客户端连续给服务器发送了6k的数据,每次发送1k
5.10次,服务器告诉客户端:发送的6k数据以及接收到,存储在缓冲区中,缓冲区数据已经处理了2k,窗口大小是2k
6.11次,服务器告诉客户端:发送的6k数据以及接收到,存储在缓冲区中,缓冲区数据已经处理了4k,窗口大小是4k
7.12次,客户端给服务器发送了1k的数据8.13次,客户端主动请求和服务器断开连接,并且给服务器发送了1k的数据
9.14次,服务器回复ACK 8194, a:同意断开连接的请求 b:告诉客户端已经接受到方才发的2k的数据c:滑动窗口2k
10.1516次,通知客户端滑动窗口的大小
11.17次,第三次挥手,服务器端给客户端发送FIN,请求断开连接
12.18次,第四次回收,客户端同意了服务器端的断开请求

6.TCP三次握手、四次挥手的状态转换

ClientServer
SYN_SENT(connect())LISTEN(listen())
SYN_RECVD
ESTABLISHEDESTABLISHED
ClientServer
FIN_WAIT_1 (close())CLOSE_WAIT
LAST_ACK(close())
FIN_WAIT_2
TIME_WAIT

主动断开连接的一方, 最后进入一个 TIME_WAIT状态, 这个状态会持续: 2msl
半关闭状态

7.端口复用

在最后的关闭时,出现TIME_WAIT状态,在此调用时,会出现端口占用的错误。所用要用端口复用

端口复用最常用的用途是:
防止服务器重启时之前绑定的端口还未释放
程序突然退出而系统没有释放端口

#include <sys/types.h>
#include <sys/socket.h>
// 设置套接字的属性(不仅仅能设置端口复用)
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_toptlen);
参数:- sockfd : 要操作的文件描述符- level : 级别 - SOL_SOCKET (端口复用的级别)- optname : 选项的名称- SO_REUSEADDR- SO_REUSEPORT- optval : 端口复用的值(整形)- 1 : 可以复用- 0 : 不可以复用- optlen : optval参数的大小
端口复用,设置的时机是在服务器绑定端口之前。
setsockopt();
bind();
http://www.lryc.cn/news/136394.html

相关文章:

  • PyTorch学习笔记(十七)——完整的模型验证(测试,demo)套路
  • WPF开篇
  • linux 压缩解压缩
  • centos9 mysql8修改数据库的存储路径
  • 【C++】<Windows编程中消息即事件的处理>
  • 数据库SQL语句使用
  • 从零开始 Spring Cloud 12:Sentinel
  • @Resurce和@Autowired的区别
  • ResNet简介
  • 了解单例模式,工厂模式(简单易懂)
  • 【中危】 Apache NiFi 连接 URL 验证绕过漏洞 (CVE-2023-40037)
  • 【Git版本控制工具使用---讲解一】
  • NLP | 基于LLMs的文本分类任务
  • 攻防世界-base÷4
  • 【Java转Go】快速上手学习笔记(三)之基础篇二
  • 【vue 引入pinia与pinia的详细使用】
  • USACO18DEC Fine Dining G
  • fckeditor编辑器的两种使用方法
  • 数据结构,查找算法(二分,分块,哈希)
  • C++(Qt)软件调试---gdb调试入门用法(12)
  • shell和Python 两种方法分别画 iostat的监控图
  • 设计模式(9)建造者模式
  • PHP 创业感悟交流平台系统mysql数据库web结构apache计算机软件工程网页wamp
  • 工作流程引擎之flowable(集成springboot)
  • leetcode54. 螺旋矩阵(java)
  • go gorm 查询
  • Flutter GetXController 动态Tabbar 报错问题
  • Redis(缓存预热,缓存雪崩,缓存击穿,缓存穿透)
  • UE4/5Niagara粒子特效学习(使用UE5.1,适合新手)
  • from moduleA import * 语句 和import moduleA 的区别