Devin's Blog

Diversity is essential to happiness

0%

网络通信(2)

网络层和传输层

  之前说的是以太网协议,这里我们看网络层和传输层.
  我们知道以太网是依靠MAC地址来发送数据的,理论上单单依靠MAC地址,上海的网卡就可以找到在北京的网卡,这在理论上是可以实现的.

  但是它有一个严重的缺点,以太网采用广播的方式去发送一个数据包,如果每个程序员人手一个包的话,这样不仅效率低,而且发送者和接受者局限在子网当中.

  也就是说,如果两个主机不在同一子网当中,广播是没有办法传输的.这种设计是比较合理的.否则互联网上每一台计算机都要收到这个包,这将是一场灾难.

  互联网是由无数个子网组成的巨型网络.如果北京和上海在同一个子网络中,这几乎是不可能的.所以我们需要寻找以这个方法来区分哪些MAC地址是同一子网络的,哪些不是.
  如果是同一子网的话,就使用广播的方式去发送数据,否则就选择路由的方式发送.
  而路由的意思是如何向不同的子网分发数据包,这个是一个非常庞大的主题.我们这里不展开说.
  非常遗憾的是MAC地址本身是不能做到这一点的,MAC地址只和厂商有关,和网络环境无关,这就导致了网络层的诞生.


#网络层
  网络层的作用是引进了一套新的地址,让我们能够区分出不同的计算机是否处于同一个子网内.这一套地址就叫网络地址,简称网址.
  网络层出现后,每一台计算机都有两个地址,一个是MAC地址,一个是网络地址.这两个地址是没有关系的.MAC地址是和网卡绑定的.而网络地址是由管理员分配的.他们只是随机的组合在一起.

  网络地址帮助我们确定计算机所在的子网络.
  MAC地址将我们的数据包发送到子网络中的目标网卡.
  所以从逻辑上,我们判断是先处理网络地址,再处理MAC地址.

由此引出IP协议,IP协议是指规定网络地址的额协议,他所定义的地址就是IP地址.目前广泛采用的是ipv4协议.这里不涉及ipv6的内容.
Ipv4是由32个二进制数组成的.我们习惯的把它分成4段的10进制数字.

192.168.1.30
11000000- 10101000- 00000001- 00011110

  他的范围是0.0.0.0-255.255.255.255
  在互联网上,每一台计算机都被分配一个IP地址,这个地址成两部分.
  前三段(如 192.168.1)为一部分,代表网络
  最后一段(如 30),代表主机,用这个30来确定这个主机
  同一子网的计算机,他们的网络部分应该是一样的.

192.168.1.1 和192.168.1.2
假设上面的IP地址的网络部分是前面的24位,也就是前三段,因为他们的网络部分相同,所以他们处于同一子网.

  但是有一个问题,单单从IP地址的话,我们是没有办法判断网络部分的.刚刚我们能判断,有一个前提.我们假定前三段是网络部分,但实际上,IP地址的网络部分到底是前面的24位还是16位,从IP地址本身是看不出来的.
那么如何从IP地址上判断两个计算机是不是处于同一子网.

  这就引出了另外一个参数,子网掩码.所谓的子网掩码就是表示子网络特征的一个参数.它在形式上也是类似一个IP地址,同时也是一个32位的2进制数字,它的网络部分全是1,主机部分全是0.

如 192.168.1.3
假设前面24位是网络部分,后面8位是主机部分.那么它的子网掩码就是255.255.255.0.
这个数字换算成2进制,前面24位都是1,后八位都是0.
当我们真的子网掩码之后,我们就可以判断任意的两个IP地址是否处于同一子网,方法是将这两个IP地址与子网掩码分别进行AND运算.然后比较他们的的结果是否一致.相同则表明在同一子网.反之,这不在.

#总结
IP协议的主要作用是

  • 为每一台计算机分配一个IP地址
  • 确定哪些地址再同一子网内

IP数据包

head ———data———
  根据IP协议发送的数据包就叫做IP数据包,那其中必然包含了IP的地址信息
  我们之前说过,以太网的数据包只包含一个MAC地址,并且没有IP地址的栏位,我们不需要修改数据包的定义,增加数据包的栏位.在说到以太网额那节课,我们说到:发送一个帧,帧里面有一个表头和数据.
  实际上我们不必要去添加一个栏位去存储IP数据包.我们可以把IP的数据包直接放进以太网数据包中的data部分.所以不用修改以太网的规格.这就是互联网分层结构的好处.上层的变动完全不会下层的结构.
  在程序开发的时候,也是一个道理.假设设计一个接口,用一个对象把参数封装起来.只要给对象添加一个内部属性,避免了一次次的添加参数.

  具体到IP数据包,它也是有head和data两个部分,* head主要包含版本号,长度,IP地址这样的信息.

  • data是IP数据包的具体内容.
    IP数据包被放入以太网数据包内后,数据包就会变成
Ethernet head IP head data

  在这个结构中,IP head 在20-60字节之间 整个IP数据包长度为65535字节,所以理论上一个IP数据包的数据部分最长是65515.
我们前面提到,以太网的数据部分最长只有1500字节,所以ip数据包已经超过了1500字节,那么它就要分割成多个以太网数据包分开发送.

  有一点值得一提,因为IP数据包是放在以太网数据包里发送的,所以我们必须同时知道两个地址.一个是对方的MAC地址,另一个是对方的IP地址.通常情况下,对方的IP地址是已知的,但是却不知道对方的MAC地址.

  这个时候就涉及到ARP协议.我们假设存在两台计算机,这两台计算机就会分成两种情况.

  • 两台计算机不在同一子网 所以他没有办法知道对方的MAC地址,只能把数据包传输到两个子网连接的网关进行处理.

  • 两台计算机在同一子网,这个时候就可以使用ARP协议,得到对方的IP地址.

  ARP协议也是发送一个数据包,这个包也是包含在以太网的数据包中,他包含了目标主机的IP地址,MAC地址.
  他知道对方的IP地址,但是不知道地方的MAC地址,所以他零时用了6组16进制的数字去表示这是一个广播的地址,他所在子网的每一个主机都会收到这个数据包.
  当这些主机收到这些数据包之后,他们把IP地址提取出来和自己的IP地址进行比较.如果都是相同的就做一个回复.告诉对方我就是你要找的目标主机,并且把自己的MAC地址上报上去.如果不相同则丢弃这个包.

  总之,有了ARP协议之后,我们就有了同一子网内的主机的MAC地址,然后把数据包发送给任意一台主机.

  我们有了MAC地址和IP地址,我们可以在两台主机上建立通信.现在的问题是同一台主机上有许多的程序都需要网络,比方说一边看网页,一边打开聊天软件.当一个数据包从互联网上发过来的时候,你怎么知道他是表示网页还是聊天内容.

  也就是说,我们还需要一个参数,来表示数据包到底被哪一个进程使用.这个参数就叫端口(Port),他其实每一个使用网卡的进程的编号,每一个数据包都会发送到计算机的特定端口上.所以不同的进程就会获取到自己所需要的数据.

  这个端口号是0-65535之间的整数.真好是16个2进制位.0-1023的端口被系统占用.所以我们在本地启动80或者443的时候会提示我们权限不够.用户一般只能选择在1023以上的端口.

  不管是浏览网页还是在线聊天,程序都会随机选择一个端口与服务器的端口做一个联系.

#传输层
  传输层的功能就是建立端口到端口之间的通讯.相比之下,网络层是建立主机到主机之间的通讯.只要确定了主机和端口,我们就可以实现程序和程序之间的交流.所以unix系统把主机加端口叫做套接字(Socket).有了他之后就可以进行网络编程了.

说到传输层不得不说,两个重要的协议
  UDP和TCP
而他的格式几乎就是数据前面加上端口号
UDP的数据包也是由head和data组成.

head data__
head部分定义 send port 和receive port
数据部分就是要发送的数据

然后把UDP数据包放到IP数据包的data部分
我们前面又说到IP数据包又是放在Ethernet协议的data部分
所以现在来看的话 Ethernet数据包变成现在这样

Ethernet head IP head UDP head __UDP data
  UDP的head部分只有8个字节,总长度不会超过65535字节,刚好可以放进一个IP数据包.

  这种协议的优点是简单,容易实现.但是缺点是可靠性差.数据包发送之后,不知道对方是不是已经收到了.为了解决这个问题,TCP协议应运而生.

  TCP协议相对比较复杂,可以粗略的认为是有确认机制的UDP协议.每发送一次数据包都要进行确认.如果有一个数据包有遗失的话就收不到确认.那么发送的一方就知道,需要重新发送这个数据包.

  关于TCP的三次握手,相对比较复杂.以后研究之后分享给大家


  TCP的优点是内容不容易丢失,缺点是过程复杂,实现困难会消耗比较多的资源.
  TCP数据包和UDP数据包一样都是内嵌在IP数据包中的.TCPd的数据包没有长度限制,理论上可以无线长的.但是为了保证网络的效率,TCP的数据包长度不会超过IP数据包的长度.这样会确保当个TCP的数据包不会再分割.

TCP

  • 面向连接
  • 提供可靠资源
  • 点对点
  • 资源消耗高
    UDP
  • 无连接 (在发送数据前不需要建立连接)
  • 不保证可靠
  • 实时性很强
  • 一对一 ,多对一,多对多
  • 资源消耗少