读书笔记-《网络是如何连接的》

以前老是觉得学习什么东西应该由浅入深,一步一步步入深渊。现在感觉好像倒过来也是可行的当然拿到一本书即使看不懂也能坚持看下去才行。主要是网络这块真是如此,最早看计算机网络第五版,云里雾里的那些什么带碰撞检测是载波侦听搞的很狼狈,后来看详解TCP/IP感觉就好一点,这两天看到Kindle里的网络是怎么连接的,终于有山重水复疑无路,柳暗花明又一村的感觉了,把一些知识点和之前的困惑记录一下。

|网络应用程序(浏览器、foxmail、web服务器)---|
|----------------------------------------|
|---------Socket库------------[DN解析器]--|
|------ [20]TCP----【OS】-----[20]UDP-----|
|[ICMP]-------0x0800:IP----[0x0806:ARP]--|
|----------------网卡驱动程序--------------|
|--------------------网卡-----------------|

1.浏览器输入网址

  • URL:协议//web服务器/目录/文件
  • HTTP 1.1 Method:HEAD、GET、POST、PUT、DELETE、OPTIONS、TRACE、CONNECT
  • 生成HTTP请求消息
#第一行请求的内容
<method> <uri> <HTTP/1.1>
#以下是字段名和值
Authorization:身份认证
Host:服务器IP和端口号
User-Agent:客户端软件信息
Accept:客户端支持的MIME类型
Range:指定获取的数据范围
Connection:是否保持连接
Via:记录途中的代理和网关
#空行
#消息体

#响应消息第一行 HTTP/1.1 200 OK
http版本+状态码+响应短语

  • 浏览器使用Socket库中的DN解析器(gethostbyname)向DNS发UDP消息查询IP
  • 域名记录:
---
|Domain:|bblu.tk  
| Class:|IN[只剩这一个类型]   
| Type: |Address|MaileXchange  
| Data: |167.211.34.1|10 mail.163.com  
---

ps:网络层依靠ARP协议IP->MAC

2.浏览器交给系统的协议栈

socket:程序组件名称
Socket:系统协议栈库【加州伯克利分校BSD系统c库】
套接字:管道两端接口

IP地址的子网相当于小区,机器号相当于楼号,端口号相当于房间号。一台计算机内有许多网络通信客户端,一个楼内有许多单元房。

  • 调用socket组件创建套接字,协议栈为这个套接字随机分配一个可用的端口号并返回一个描述符给客户端。
  • 调用connect组件(描述符,IP,port)
  • 调用Socket库write组件委托系统把消息写入协议栈
  • Socket库中的read程序组件委托系统协议栈接收消息
  • HTTP协议规定web服务器响应完消息后应该主动断开,所以web服务器会首先调用close断开连接。

    实际收发数据的是协议栈->网卡驱动->网卡

3.[TCP/IP]协议原型是一个后来拆分了

TCP负责客户端内,IP负责客户端外
协议栈通过TCP收发数据:出错重发

  • 1.创建套接字
  • 2.连接服务器
  • 3.收发数据
  • 4.断开删除套接字

协议栈通过UDP收发数据:客户端自己负责

3.1套接字的实体就是通信控制信息

协议栈是根据套接字记录的控制信息进行工作的 windows使用netstat -ano 查看套接字

ProtoLocalAddressForeignAddressStatePID

网络包{[IP][TCP][Data]}
[A]SYN=1——>[B] 歪歪你是B吗?
[A]<——ACK=1[B] 嗯嗯我是B你是A吗?
[A]ACK=1——>[B] 我是A,是这样。。。(开始会话)

经过三次握手之后的connection从业务角度可以称为session【会话】

以太网的MTU=1500字节,PPPoE有额外的头信息MTU会变小   
1500- 20-20= 1460  
MTU - HEAD = MSS【最大分段大小】 

起始帧分界符SFD

|-----帧 -----|以太包--------------|  
[56b报头/8bSFD][MAC][IP][TCP][Data][32b帧校验FCS]  
|-------------|-IP负责--|  

IP协议根据IP地址查找包的传输方向,即下一个路由器的位置,接下来委托以太网协议把包传输过去,下一个路由器的MAC地址被写入到MAC头部中去,IP模块给TCP包加了两个头MAC头和IP头,PhysicalLayerDevice(PHY)模块将MAC模块产生的信号转换为可以在网线上传输的格式还有监听有没有信号进来,半双工模式下信号碰撞后终止发送,广播阻塞随机延时后重试。

  • ARP协议通过广播,对应的终端会回应自己的MAC。ARP缓存一般保存几分钟,刚刚修改IP地址后可能会发生通信异常。
  • 以太网报头给了56比特的101010…交替的序列是给接收方同步时钟的网络传输速率就是时钟的频率比如10Mbit/s或者100Mbit/s,从SFD后马上进入工作状态。前面的序列可以理解为idle后面的SFD可以当作是读取指令。
  • 发送帧使用集线器的半双工模式或交换机的全双工模式。接收方先用FCS做有效检查再比对MAC地址如果不一致将丢掉,相同就将包放入缓冲区由网卡发起一个中断通知CPU,CPU告诉在对应中断号注册的网卡驱动的中断处理程序去取包进行下一步操作,类型是0x0080的包给TCP/IP协议栈,0x809B的包给AppleTalk的协议栈。
  • 进入TCP/IP后如果发现IP地址错误IP模块会通过ICMP消息通知发送方,但是有网络转发功能的服务器会转发包。

主要的ICMP消息
类型:描述
0:EchoReply
3: DestinationUnreachable
4: Source Quench路由器负载报警
5: Redirect 包的出入口相同告诉发送方下一个路由让它直接发过去
8: Echo Ping命令发送的消息,接收方返回一个EchoReply
11: TimeExeccded 超过IP头部的TTL被丢弃通知发送方
12:IP头错误被丢弃

  • IP协议里接收到开启分片的包还要分片重组
  • PromiscuousMode混杂模式下网卡不检查接收方MAC地址照单全收。
  • 网络超时就是指指定时间没有收到返回的ACK号。

尽管我们说IP模块负责将包发给对方,但实际上将包从发送方传输到接收方的工作是由集线器、路由器等网络设备来完成的。

发送数据方会把数据的字节序号+长度一同发给接收方,接收方把字节序号+1设置为ACK应答给发送方,配合滑动窗口ACK可以间隔回应,实际使用为了安全开始传输会给字节序号一个随机数。

ps:Gateway在TCP/IP的世界里就是路由器

4.UDP

如果数据很短一个包就能轻松装下就没有必要考虑进度了,出错也就是把一个包重新发一下,代价却比TCP小的多。比如DNS查询,对方的回复就是接收确认。

UDP可以发送的最大数据是由IP包头的全长字段16b决定的,IP协议包最大长度是65535,再减去20IP+8UDP等于65507,需要IP模块分片传输。

5.交换机和路由器的包转发操作

实际上路由器中路由表的目标IP地址只需要表示子网部分的比特值就可以了,主机号部分全部为0(也有一些IP地址主机号不是全部为0)。

  • 路由器的端口并不只有以太网一种,不同线路和局域网类型支持的最大包也不同。比如PPPoE协议遇到这种情况,可以使用IP协议中定义的分片功能对包进行拆分,缩短每个包的长度。需要注意的是,这里说的分片和第2章介绍的TCP对数据进行拆分的机制是不同的。TCP拆分数据的操作是在将数据装到包里之前进行的,换句话说,拆分好的一个数据块正好装进一个包里。从IP分片的角度来看,这样一个包其实是一个未拆分的整体,也就是说,分片是对一个完整的包再进行拆分的过程。
  • 程序不允许分片或者已经分片的包不能分片。
  • 公网地址紧缺后把公网没分配的三个段拿出来当成私有地址
  • 10.~ 172.16.~ 192.168.~ ,以太网外网部分分配PublicAddress,内网部分通过地址转换(NAT)机制上网,即在转发包时头部的IP地址和端口号,NAT设备一般是路由器中的16b端口号可以表示65536个值除去前面保留的1024个其余的都可以映射给内网的上网设备。

ps:网络字节序列为什么是大端的?因为所有的协议头都在前面,不先把协议头发出去网络协议没法工作。

Leave a Comment