计算机网络基础(一)
应用层#
- 在Linux系统中输入命令:
此时再打开一个终端,输入命令:nc www.baidu.com 80
netstat -natp
发现本地与百度已经建立起一个连接,进程号50603。此时如果本地向和百度进行通讯,则请求必须遵循HTTP协议。在第一个终端中继续输入命令:GET / HTTP/1.0 # 两次回车
百度则返回给主机响应头和响应体(HTML),依然遵循应用层的HTTP1.0协议。 - 在Linux系统中输入命令:
curl baidu.com -v
上述连接采用了HTTP1.1协议。那么它和1.0协议的区别是什么呢?
如果我们使用命令新建一个连接:
如果使用HTTP1.0协议,即输入GET / HTTP/1.1后两次回车,我们可以得到baidu.com的响应且连接依然存在;然而如果输入的是GET / HTTP/1.0,那么我们接收到响应后连接就中断了:telnet baidu.com 80
因此在HTTP1.0中,连接将在响应后立即关闭,这意味着必须为每个查询打开新的连接。 HTTP1.1在同一个连接中只能有一个正在处理的请求,但是可以依次处理多个请求(当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的TCP连接)。而HTTP2.0优于HTTP1.1的好处之一是,我们可以在同一连接上有多个处理中的请求。 - 而如果主机想要和其他的服务器,如Tomcat,Redis等,则要遵循相应的应用层协议。
例如连接Redis服务器,输入相关命令:
上述通讯便遵循了Redis的应用层协议。而主机输入的请求是怎么传输到服务端的呢?主机是如何与服务端建立连接呢?这便是内核层的工作。
传输控制层#
应用层与传输控制层之间通过套接字(Socket)传递数据,套接字是传输控制层与应用层的一个中间媒介,位于两层之间。
- SYN:Synchronous 建立连接
- ACK:Acknowledge 确认
- FIN:Finish 结束连接
当Linux系统中,使用抓包工具tcpdump抓取数据包:
# -nn : 数字的方式显示IP和端口,一个n是ip
# -i : 网卡
# port : 端口号
tcpdump -nn -i eth0 port 80
当tcpdump开始监听eth0后,使用curl命令连接到百度服务器:
curl www.baidu.com :80
- 192.168.150.11 : 本机ip地址
- 220.181.38.149 : 服务端ip地址
- "[S]" : SYN
- "[P]" : PUSH(发送方通知接收方传输层应该尽快的将这个报文段交给应用层)
- "[.]" : ACK
- "[F]" : FIN
- "length 168" : 客户端发出的请求头
- "length 1460/1321" : 服务端发出的响应头和响应体,分两个包传输。
- "win" : 大小表示内核中可用的TCP缓冲区长度,可用来缓冲接收到的数据包。大小为0意味着接收端有很多滞后要从其套接字缓冲区中捕获,发送端必须暂停发送数据包,以便接收端能够应付。这种流量控制防止了接收端慢和发送端快的问题。
网络层#
IP#
- IPv4 点分字节:四个字节,一个字节8个二进制位(0~255)
例:192.168.150.1 - 在Linux系统中使用命令:
得到网卡配置文件的相关信息:vi /etc/sysconfig/network-scripts/ifcfg-eth0
- #HWADDR : 物理地址(MAC地址)
- IPADDR : 主机IP地址
- NETMASK : 子网掩码
- GATEWAY : 网关
- DNS : DNS服务器(将域名转换为IP地址)
- 网络号(网段)
通过ip地址与子网掩码进行二进制按位与运算得到,例如:
主机ip:192.168.150.11
子网掩码:255.255.255.0
则该局域网网段为192.168.150.0,该主机的主机号为11。在此局域网下的其他主机ip可能为192.168.150.1, 192.168.150.2, 192.168.150.3……等。
Route(路由表)#
在Linux系统中使用命令:
route -n
- Destination : 可以连接的网络地址
- Gateway : 网关
- Genmask : 掩码
- Iface : 网络连接走的接口为eth0
路由表的每一行代表一个路由规则:将服务端ip与掩码进行二进制按位与运算。如果计算得到的地址存在于本机路由表中的Destination中,则传输控制层可以向该服务端发送数据包,从而建立连接。
例如:服务端为同一局域网的另一台主机,ip地址192.168.150.n。那么它与掩码255.255.255.0二进制按位与运算后的结果为192.168.150.0,即路由表中第一行的Destination。第一行的网关为0.0.0.0,代表不需要通过网关,可以直接通过eth0发送数据包;
如果服务端为baidu,ip地址220.181.38.149。那么它与掩码0.0.0.0进行计算后的结果为0.0.0.0,即路由表中第三行的Destination。第三行的网关为192.168.150.2,因此需要将数据包发送到此网关。当网关完成“下一跳”后,数据包才会到达服务端。
思考一个问题:#
上述第二个例子中,如果传输控制层发出的数据包上只写一个ip地址,那么应该写192.168.150.2还是220.181.38.149呢?
如果写192.168.150.2,网关可以接收到数据包,但是它却不知道这个数据包后续应该交给谁;如果写220.181.38.149,网络层就不知道该把这个数据包交给哪个网关了,因此需要链路层为我们完成这项任务。
链路层#
在Linux系统中使用命令:
arp -n
查看本机的arp协议,即ip地址与网卡物理地址之间的映射关系:
而当我们使用命令:
ping www.baidu.com
建立一个连接后,再次查看arp协议,会发现增加了一对映射关系:
实际上arp完成了一个在局域网广播请求的过程:谁有192.168.150.2的物理地址?请把它发送给我。
如果把数据包比作一个三层包装的邮政包裹,为了能够准确地将它送往服务端,链路层给它的最外层写上了网关192.168.150.2的MAC地址00:50:56:f7:53:2b,网络层给中间层写上了服务端的IP地址220.181.38.149,传输控制层则在最内层写上了服务端监听的端口号PORT:80。
在每一跳中遵循类似的路由查找过程,直到数据包到达目标服务器。数据包的传输过程中,ip地址和端口号始终不变。类似于数据结构中的链表,MAC地址永远指向下一个目标。
我们再次使用tcpdump进行抓包,这次还包括了arp广播发出的数据包:
tcpdump -nn -i eth0 port 80 or arp
可以发现在TCP发出握手请求之前,arp就会发起广播请求:
who has 192.168.150.2 tell 192.168.150.11
这里的192.168.150.2便是网关的ip地址,192.168.150.11则是主机的ip地址:
当得到回复:
Reply 192.168.150.2 is -at 00:50:56:f7:53:2b
链路层便得到了指定网关的物理地址。
作者:koktlzz
出处:https://www.cnblogs.com/koktlzz/p/14113146.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现