套接字传输TCP/IP数据协议过程

网络协议栈是操作系统根据网络模型的具体实现。

用户层可以借助于操作系统提供的功能进行与其他的主机进行网络通信

交互主要分为以下几个步骤:

1 创建套接字

什么是套接字

套接字指的实体是通信控制信息,控制信息里面包含了通信对象的IP地址,端口号和通信操作进行状态。

在linux中,套接字的实体所指的是套接字缓冲区域。

一个套接字缓冲区代表了一个网络封包,套接字缓冲区可以代表不同的网络封包。

linux里面执行如下命令可以看到有多少个套接字:

netstat

上面就是所有的套接字以及它所包含的信息。

创建套接字指的是在内存中开辟一个存储空间,并向这个空间内写入初始化的信息。

如下所示就是python 创建socket的代码,可以看到在进行初始化的时候,传入了

绑定地址和端口信息。这些都会存储到控制信息中(linux中对应套接字缓冲区)。

另外可以看到每一个套接字包含了不同的状态。

import socket

sk = socket.socket()
sk.bind(("127.0.0.1",8080))
sk.listen(5)
conn,address = sk.accept()
sk.sendall(bytes("Hello world",encoding="utf-8"))

2 连接服务器

所谓的连接就是客户端和服务器端交换控制信息。

负责保存控制信息的头部

有些控制信息在通信的整个过程中都是需要的,这些控制信息需要保存在所发送的包的内部。

这些信息被称为“头部”,不同的协议和网络层在处理包的过程中都会加上自己的头部。

为了便于区分这些头部被称为“TCP 头部”, 以太网头部和IP头部。

在连接和断开阶段由于没有对应的实际数据,所以传递的仅仅是网络包。

连接操作的整个过程。

tcp的三次握手

tcp首先发起请求,将syn设置为1

添加tcp头部,并交给ip模块传递包。

服务器接收到请求之后,找到对应的套接字,并返回消息。返回的时候syn要设置为1,ack也要设置为1

如果因为某些原因无法连接时,则将rst字段设置为1。

客户端收到之后要返回一个数据包,并将ACK设置为1,这样整个连接也就建立了。

 

3 传输数据

连接建立之后,客户端就可以调用write()函数进行数据的传输。

对于较小的数据片,协议栈会等到数据填满后打包发送,这个数据的容量就是mtu值。

如果应用程序发送的数据包较小,那么会影响发送的效率,协议栈会等到数据达到mtu值之后才会发送。

当然这个是由程序来控制的。可以选择不缓存而立马发送,但是这样会造成网络的拥挤。

如果数据包过大,超过了mtu值那么就需要对网络包进行拆分。分成一个个的小包发送出去。

这样网络包就发送出去了,但是tcp是一个安全可靠的传输协议,必须保证包能够抵达服务端。

这样就需要一定的机制来保证。

  • 使用ack确认网络包已经收到

 

根据包的平均往返时间来调整ACK号的等待时间。

 

滑动窗口机制的原理,ACK值在返回的过程中可能会造成延迟,如果延迟过高,那么

必然会造成重传,如果重传势必会造成网络更加拥挤。但是如果设置等待网络ACK 包

的时间过长也会导致网络速度变慢,因此需要为延迟设置一个合适的时间。

4 断开连接

5 IP与以太网的包收发操作

包结构

网卡是物理层设备,负责将电信号转化为数字信号。虚拟网卡尤其是linux的tap设备

是对网卡的模拟,它并不负责将电信号转化为数字信号,而是一个软件,负责数字信号

的传输。

TCP协议的目的是保证数据的安全和可靠传输,所以它有三次握手和三次挥手的功能。

这整个算是传输层的能力。UDP也一样,不过它不具备可靠传输的能力。

内核协议栈的IP模块的主要功能是对包进行封装传输。它并不关心TCP做了哪些事情。

举个例子来说,我们在邮局寄东西的时候,汽车的运输人员,他们不关心运输的东西

是什么,每一个物品都封装成了一个个的包裹,包裹上面有面单,上面包含了发送地址和寄出地址。

 

 

IP模块在接收到包之后会做两件事情,添加IP头部和MAC头部。

MAC头部在IP头部的前面,由于在处理的时候先处理二层的MAC头部,再

处理三层的IP头部。

网卡有对应的网卡驱动程序,网卡的内部结构如下图所示。它的主要功能是

将数字信号转换为电信号并传输出去。

 

参考文献:计算机网络是怎么连接的

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章