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

1.TCP和UDP区别

都为传输层协议

UDP:用户数据报协议,面向无连接,可以单播,多播,广播,面向数据报,不可靠

TCP:传输控制协议,面向连接的,可靠的,基于字节流,仅支持单播传输

UDP TCP
是否创建连接 无连接 面向连接
是否可靠 不可靠 可靠的
连接的对象个数 一对一、一对多、多对一、多对多 一对一
传输的方式 面向数据报 面向字节流
首部开销 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)

cpp 复制代码
int socket(int domain,int type,int protoco1);
	-功能:创建一个套接字
	-参数:
		- domain : 协议族
			AF_INET : ipv4 
			AF_INET6 : ipv6
			AF__UNIX,AF_LOCAL :本地套接字通信(进程间通信>
		- type : 通信过程中使用的协议类型
			SOCK_STREAM ︰流式协议
			SOCK_DGRAM︰报式协议
		-protoco1 : 具体的一个协议。一般写0
			- SOCK_STREAM︰流式协议默认使用 TCP
			- SOCK_DGRAM︰报式协议默认使用UDP
	-返回值:
		-成功:返回文件描述符,操作的就是内核缓冲区。-失败:-1

int 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 :未连接的和已经连接的和的最大值,5

int 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协议的传输时的完整性和顺序性

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

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

c 复制代码
# 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.第15、16次,通知客户端滑动窗口的大小
11.第17次,第三次挥手,服务器端给客户端发送FIN,请求断开连接
12.第18次,第四次回收,客户端同意了服务器端的断开请求

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

Client Server
SYN_SENT(connect()) LISTEN(listen())
SYN_RECVD
ESTABLISHED ESTABLISHED
Client Server
FIN_WAIT_1 (close()) CLOSE_WAIT
LAST_ACK(close())
FIN_WAIT_2
TIME_WAIT

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

7.端口复用

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

端口复用最常用的用途是:

防止服务器重启时之前绑定的端口还未释放

程序突然退出而系统没有释放端口

c 复制代码
#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();
相关推荐
C15751X30 分钟前
联通光猫(烽火通信设备)改桥接教程
网络
yaoxin5211231 小时前
第二十九章 TCP 客户端 服务器通信 - 记录的拼接
服务器·网络·tcp/ip
网络安全Ash1 小时前
运维之网络安全抓包—— WireShark 和 tcpdump
网络·网络协议·安全·网络安全
向阳12182 小时前
http 流量接入 Dubbo 后端服务
网络协议·http·dubbo
萤火夜3 小时前
Linux之网络基础
网络
xxtzaaa4 小时前
住宅IP怎么在指纹浏览器设置运营矩阵账号
网络·网络协议·tcp/ip
okmacong4 小时前
3、集线器、交换机、路由器、ip的关系。
网络·tcp/ip·智能路由器
添砖java_8574 小时前
TCP流套接字编程
网络·网络协议·tcp/ip
TimberWill4 小时前
字符串-07-判断两个IP是否属于同一子网
java·网络协议·tcp/ip
ZachOn1y4 小时前
计算机网络:运输层 —— TCP 的超时重传机制
网络·网络协议·tcp/ip·计算机网络·tcp·超时重传