Socket 套接字通信(及TCP介绍)

Socket 套接字通信

全员干货~,知识点相对底层!

文章目录

      • Socket 套接字通信
        • 1.TCP/IP 基础知识
          • 1.1TCP的三次握手 (面试重点)
          • 1.2 TCP的四次挥手(面试重点)
        • 网络通信基础
        • TCP服器端通信流程
        • 客户端的通信流程

1.TCP/IP 基础知识

Socket 套接字通信(及TCP介绍)_第1张图片

TCP(传输控制协议) 是一种面向连接的、可靠的、基于字节流的通信协议,数据在传输前要建立连接,传输完毕后还要断开连接。

客户端在收发数据前要使用 connect() 函数和服务器建立连接。建立连接的目的是保证IP地址、端口、物理链路等正确无误,为数据的传输开辟通道。

TCP建立连接时要传输三个数据包,俗称三次握手

TCP 数据报结构

Socket 套接字通信(及TCP介绍)_第2张图片

  1. 序号:用于标识从 计算机A 发送到 计算机B 的数据包的序号,发送数据时对此标记
  2. 确认号:Ack ,客户端 和 服务器端 都可以发送 Ack = Seq +1
  3. 标志位:每个标志位占用1Bit,共有6个,分别为 URG、ACK、PSH、RST、SYN、FIN
URG:紧急指针(urgent pointer)有效。
ACK:确认序号有效。
PSH:接收方应该尽快将这个报文交给应用层。
RST:重置连接。
SYN:建立一个新连接。
FIN:断开一个连接。
1.1TCP的三次握手 (面试重点)

过程描述:

  1. 首先 客户端 发送 连接请求报文
  2. 服务器端 接受 连接后回复ACK报文 , 并为这次连接分配资源
  3. 客户端 接受到 ACK报文后 也向服务器端发送ACK报文,并分配资源,这样TCP连接就建立了

Socket 套接字通信(及TCP介绍)_第3张图片

注意三次握手的关键是要确认对方收到了自己的数据包,这个目标就是通过“确认号(Ack)”字段实现的。计算机会记录下自己发送的数据包序号Seq,待收到对方的数据包后,检测“确认号(Ack)”字段,看Ack = Seq + 1是否成立,如果成立说明对方正确收到了自己的数据包

注意: 3次握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼此已准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。

1.2 TCP的四次挥手(面试重点)

断开连接让计算机释放不再使用的资源。如果连接不能正常断开,不仅会造成数据传输错误,还会导致套接字不能关闭,持续占用资源,如果并发量高,服务器压力堪忧。

四次挥手即终止TCP连接,断开一个TCP连接时,需要客户端和服务器端总共发出4个包已确认连接的断开。在socket编程中,这一过程由客户端或服务器端任一方执行close()来触发

Socket 套接字通信(及TCP介绍)_第4张图片

Socket 套接字通信(及TCP介绍)_第5张图片

参考四次握手

网络通信基础

网络通信的主体主要分为两部分: 客户端和服务器端。在客户端和服务器通信的时候需要频繁提到三个概念:IP、端口、通信数据

**字节序: **字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序,对单字节来说没有字节序问题(字符串是单字节集合体),因此字符串也没有字节序问题。

计算机中字节存储机制主要有两种: 大端,小端

  • 主机字节序 (小端):

数据的低位字节存储在内存的低位地址,数据的高位字节存储到内存的高位地址

  • 网络字节序(大端):

数据的低位字节存储在内存的高位地址,数据的高位字节存储到内存的低位地址

​ 套接字通信过程中操作的数据都是大端存储的,包括:接收/发送的数据、IP地址、端口。

TCP通信流程(十分重要)

TCP 是一个面向连接的,安全的,流式传输协议, 这个协议是一个传输层协议

面向连接:是一个双向连接,通过三次握手完成,断开连接需要通过四次挥手完成。
安全:tcp 通信过程中,会对发送的每一数据包都会进行校验,如果发现数据丢失,会自动重传
流式传输:发送端和接收端处理数据的速度,数据的量都可以不一致

Socket 套接字通信(及TCP介绍)_第6张图片

TCP服器端通信流程

1.创建用于监听的套接字,这个套接字是一个文件描述符

int Ifd = socket();

2.将得到的监听的文件描述符和本地的IP端口进行绑定

bind();

3.设置监听(成功后开始监听,监听客户端的连接)

listen();

4.等待并接受客户端的连接请求,建立新的连接,会获得新的文件描述符(通信)没有连接请求就阻塞

int cft = accpet();

5.通信,读写操作默认是阻塞的

//接受数据
read();  / recv()
//发送数据
write(); / send();

6.断开连接,关闭套接字

close();

文件描述符

服务器端的两类文件描述符: 1.用于监听新的客户端 2.接受已建立连接的客户端数据

Socket 套接字通信(及TCP介绍)_第7张图片

文件描述符内存结构:读缓存区、写缓存区

一个文件描述符对应两块内存:一块是读缓存区,一块是写缓存区

读数据:通过文件描述符将某块内存中的数据读出来,这块内存称为:读缓存区

写数据:通过文件描述符将数据写入某块内存中,这块内存称为:写缓存区

监听的文件描述符:

客户端的连接请求发送到服务器端监听的文件描述符的读缓存区,读缓存区中有数据说明有新的客户端连接,调用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();

你可能感兴趣的:(网络编程,网络,tcp/ip,服务器)