全员干货~,知识点相对底层!
TCP(传输控制协议) 是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。
客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。
TCP建立连接时要传输三个数据包,俗称三次握手
TCP 数据报结构
URG:紧急指针(urgent pointer)有效。
ACK:确认序号有效。
PSH:接收方应该尽快将这个报文交给应用层。
RST:重置连接。
SYN:建立一个新连接。
FIN:断开一个连接。
过程描述:
注意: 三次握手的关键是要确认对方收到了自己的数据包
,这个目标就是通过“确认号(Ack)”字段实现的。计算机会记录下自己发送的数据包序号Seq,待收到对方的数据包后,检测“确认号(Ack)”字段,看Ack = Seq + 1是否成立,如果成立说明对方正确收到了自己的数据包
注意: 3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好)
,也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
断开连接让计算机释放不再使用的资源。如果连接不能正常断开,不仅会造成数据传输错误,还会导致套接字不能关闭,持续占用资源,如果并发量高,服务器压力堪忧。
四次挥手即终止TCP连接,断开一个TCP连接时,需要客户端和服务器端总共发出4个包已确认连接的断开。在socket编程中,这一过程由客户端或服务器端任一方执行close()来触发。
参考四次握手
网络通信的主体主要分为两部分: 客户端和服务器端。在客户端和服务器通信的时候需要频繁提到三个概念:IP、端口、通信数据
**字节序: **字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序,对单字节来说没有字节序问题(字符串是单字节集合体),因此字符串也没有字节序问题。
计算机中字节存储机制主要有两种: 大端,小端
数据的低位字节存储在内存的低位地址,数据的高位字节存储到内存的高位地址
数据的低位字节存储在内存的高位地址,数据的高位字节存储到内存的低位地址
套接字通信过程中操作的数据都是大端存储的,包括:接收/发送的数据、IP地址、端口。
TCP通信流程(十分重要)
TCP 是一个面向连接的,安全的,流式传输协议, 这个协议是一个传输层协议。
面向连接:是一个双向连接,通过三次握手完成,断开连接需要通过四次挥手完成。
安全:tcp 通信过程中,会对发送的每一数据包都会进行校验,如果发现数据丢失,会自动重传
流式传输:发送端和接收端处理数据的速度,数据的量都可以不一致
1.创建用于监听的套接字,这个套接字是一个文件描述符
int Ifd = socket();
2.将得到的监听的文件描述符和本地的IP端口进行绑定
bind();
3.设置监听(成功后开始监听,监听客户端的连接)
listen();
4.等待并接受客户端的连接请求,建立新的连接,会获得新的文件描述符(通信)没有连接请求就阻塞
int cft = accpet();
5.通信,读写操作默认是阻塞的
//接受数据
read(); / recv()
//发送数据
write(); / send();
6.断开连接,关闭套接字
close();
文件描述符
服务器端的两类文件描述符: 1.用于监听新的客户端 2.接受已建立连接的客户端数据
文件描述符内存结构:读缓存区、写缓存区
一个文件描述符对应两块内存:一块是读缓存区,一块是写缓存区
读数据:通过文件描述符将某块内存中的数据读出来,这块内存称为:读缓存区
写数据:通过文件描述符将数据写入某块内存中,这块内存称为:写缓存区
监听的文件描述符:
客户端的连接请求发送到服务器端监听的文件描述符的读缓存区,读缓存区中有数据说明有新的客户端连接,调用accept()函数,accept()函数会检测 监听文件描述符 的读缓存区
检测不到数据,该函数阻塞,如检测到数据,解除阻塞,新的连接建立
通信的文件描述符
客户端 和 服务器端 都有 通信的文件描述符
发送数据:调用write() /send() ,数据进入内核中
数据没有被发送出去,而是将数据写入 ”通信的文件描述符“ 对应的 写缓冲区 中
内核检测到 “通信的文件描述符” 的写缓存区中有数据,内核会将数据发送到网络中
接受数据:调用read()/recv() , 从内核读数据
数据如何进入到内核程序 程序员不需要处理 , 数据进入到 通信的文件描述符 的读缓存区中
数据进入到内核,必须使用 “通信的文件描述符”,将数据从读缓存区中读出即可
单线程的情况下客户端通信的文件描述符有一个,没有监听的文件描述符
1.创建一个通信的套接字
int cfd =socked();
2.连接服务器,需要知道服务器绑定的 IP 和 端头
connect();
3.通信
//接受数据
read(); / recv();
//发送数据
write(); / send();
4.断开连接,关闭文件描述符(套接字)
close();
客户端的通信流程
单线程的情况下客户端通信的文件描述符有一个,没有监听的文件描述符
1.创建一个通信的套接字
int cfd =socked();
2.连接服务器,需要知道服务器绑定的 IP 和 端头
connect();
3.通信
//接受数据
read(); / recv();
//发送数据
write(); / send();
4.断开连接,关闭文件描述符(套接字)
close();