Loading

计算机网络基础(一)

layer

应用层

  • 在Linux系统中输入命令:
    nc www.baidu.com 80
    
    此时再打开一个终端,输入命令:
    netstat -natp
    
    20201223170157
    发现本地与百度已经建立起一个连接,进程号50603。此时如果本地向和百度进行通讯,则请求必须遵循HTTP协议。在第一个终端中继续输入命令:
    GET / HTTP/1.0
    # 两次回车
    
    20201223165806
    百度则返回给主机响应头和响应体(HTML),依然遵循应用层的HTTP1.0协议。
  • 在Linux系统中输入命令:
    curl baidu.com -v
    
    20201223153643
    上述连接采用了HTTP1.1协议。那么它和1.0协议的区别是什么呢?
    如果我们使用命令新建一个连接:
    telnet baidu.com 80
    
    如果使用HTTP1.0协议,即输入GET / HTTP/1.1后两次回车,我们可以得到baidu.com的响应且连接依然存在;然而如果输入的是GET / HTTP/1.0,那么我们接收到响应后连接就中断了:
    20201223160159
    20201223160034
    因此在HTTP1.0中,连接将在响应后立即关闭,这意味着必须为每个查询打开新的连接。 HTTP1.1在同一个连接中只能有一个正在处理的请求,但是可以依次处理多个请求(当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的TCP连接)。而HTTP2.0优于HTTP1.1的好处之一是,我们可以在同一连接上有多个处理中的请求。
  • 而如果主机想要和其他的服务器,如Tomcat,Redis等,则要遵循相应的应用层协议。
    例如连接Redis服务器,输入相关命令:
    20201223163117
    上述通讯便遵循了Redis的应用层协议。而主机输入的请求是怎么传输到服务端的呢?主机是如何与服务端建立连接呢?这便是内核层的工作。

传输控制层

应用层与传输控制层之间通过套接字(Socket)传递数据,套接字是传输控制层与应用层的一个中间媒介,位于两层之间。
tcp

  • 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

20201210102906
命令行参数说明:

  • 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
    
    得到网卡配置文件的相关信息:
    20201210132006
    • #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

得到本机路由表信息如下:
1607578833(1)

  • 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地址与网卡物理地址之间的映射关系:
20201210142721
而当我们使用命令:

ping www.baidu.com

建立一个连接后,再次查看arp协议,会发现增加了一对映射关系:
20201210142319
实际上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地址:
20201210145003
当得到回复:

Reply 192.168.150.2 is -at 00:50:56:f7:53:2b

链路层便得到了指定网关的物理地址。

posted @ 2020-12-10 11:02  koktlzz  阅读(453)  评论(0编辑  收藏  举报