学习指导1.Python 学习资料1. 廖雪峰的官方网站 http://www./wiki/001374738125095c955c1e6d8bb493182103fac9270762a000 2. Python快速教程 http://www.cnblogs.com/vamei/archive/2012/09/13/2682778.html 3. python 帮助 2.TCPIP基础学习2.1 TCPIP协议分层2.1.1 分层原理发送端:程序员编写的应用程序通过socket 函数库的使用, 比如调sendto 或者send或者write , 这些函数在操作系统的用户态空间,进入操作系统的系统调用,调操作系统的sys_xxx 函数,进入操作系统的内核态。 内核态的网络子系统(专门处理网卡、TCPIP协议的代码), sys_sendto 判断 是UDP还是TCP,如果是TCP,则调 TCP_output 函数,TCP_output负责填写TCP首部的数据,比如发送方的端口号和接收方的端口号、以及校验和(简单校验,防止数据错误)。 紧接着进入IP层处理,调IP_output,查找路由(因为设备可能有多个网卡, 那怎么选择? 根据目的IP地址来选路,类似于查地图,找到哪个网卡), IP_output 填写发送者的IP地址和接收者的IP地址信息。 IP层首部按固定格式填好之后,那么就进入链路层(由物理层所决定,早起有的设备并没有网卡,有的是直连的电话线或者串口等设备, 而网卡的设备识别ID是MAC地址, 6个字节。) 不同的链路层处理函数是不同的,如果是网卡,则是ethernet_output, 链路层的处理则是需要填写自己的MAC地址和对方的MAC地址。 对方的MAC地址从哪里来?后面会讲到。 链路层获取到对方的MAC地址后,就把报文按固定格式填好,这个时候,所有的数据都按固定格式组装完毕, 调网卡的驱动程序的函数 physic_send 发送(会触发软中断或者加入队列,写一个消息,CPU后续从网卡获取数据发送出去。) 接收端: 接收端网卡收到数据后,触发了中断, 报文的内容被写入一个队列中,触发一个软中断, 操作系统的内核线程会去读取队列中的数据。读到数据后,先解析是以太网的格式还是其他物理设备的格式。 以太网 的首部是14个字节(目的MAC是自己网卡的,报文才允许接收, 广播报文也默认会接收) 内核线程调ethernet_input函数处理,如果是IP报文,则调 ip_input函数,进行IP首部报文正确性检查,如果目的IP地址属于自己某个网卡的,则是属于自己设备的报文,如果不是,要转给其他设备(类似于路由器)(实际情况,判断报文是不是自己设备,不是根据IP地址,而是根据路由表,后续再讲) IP_input 检查报文中的 8位协议号 信息,如果是TCP 就调tcp_input函数处理,如果是udp,则调udp_input函数处理,如果是ping报文(准备叫法是icmp),则调icmp_input函数处理。 最后tcp_input或者udp_input讲报文入了tcp或者udp的数据队列中,等程序员写的socket程序 调recv或者recvfrom函数把数据读走,继续用于自己的数据解析,如,如果是HTTP报文,则进行http报文解析处理。 2.1.2 Ping 的原理说明Ping 是一个应用程序,是通过socket 编程实现的, 通过创建一个raw socket。 socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp) 通过代码 构造IP首部、ICMP首部,将报文发送出去。 ICMP 请求 报文 8位类型和8位代码是8和0 而ping的应答报文 的type code是0和0 举例 PC1 192.168.2.1 执行ping 的应用程序,发送报文给 PC3 192.168.2.3 而实际上PC3 192.168.2.3上是没有启动应用程序的,但是结果能ping 通? 原因是? PC3 中 操作系统的内核收到ICMP 请求报文后, 直接进行了ICMP应答,即这个报文不会到达应用程序(因为不需要?只需要知道这个IP地址真实存在就OK了) ,但是这个应答报文需要 送给PC1 的应用程序? 为什么? 因为ping 是应用程序发送出来的,那么应用程序必然需要知道到底是成功还是失败或者超时了。 打开 wireshark ,选择真实的物理网卡 鼠标选择报文某个字段, 右键 选择 apply as filter 可以选择性报文, 同时也可以 && tcp 或者&& http 选择报文类型抓包 1. 宽带办理 家庭A和家庭B 属于一个小区的两家用户 ,分别办理了宽带。 家庭A的路由器和家庭B的路由器 通电后,会发送广播报文(这个时候还没有IP地址) 发送给电信的交换机(交换机转给电信路由器) ,电信路由器对 家庭A/B路由器响应, 家庭A/B 将用户名和密码填写到报文里面, 电信路由器收到报文后,根据密码进行判断,如果在自己的用户名列表且密码正确,则给每家分配一个IP地址,IP地址是201.1.1.10和201.1.1.20 ,同时在报文里面将DNS服务器 114.114.114.11的地址带给A/B 结合实际家里的路由器举例: 在浏览器输入192.168.1.1 可以查看自己家路由器的信息 10.68.166.75 就是电信路由器给家庭分配的IP地址; 10.64.0.10 和10.64.0.100 是电信路由器在分配IP地址的过程中携带回来的DNS服务器IP, 相当于组网图中的114.114.114.114 2. 手机和电脑的IP地址从哪里来的? 手机和电脑的IP的地址是从自己的路由器分配的(当然也可以手动配置IP地址,但是管理起来比较复杂),采用的是DHCP 自动分配IP地址。 比如,查看自己的电脑 点 开始 --à运行 输入 ipconfig /all 备注: 通常情况下 自己家路由器的DNS server 也是192.168.1.1 ,这里的114.114.114.114是我修改的,有时候网页访问出现问题,和DNS 有关。 手机和电脑开机后,通过DHCP协议(后续再讲)从家庭路由器 192.168.1.1 中获取IP地址和DNS服务器的IP地址,得到192.168.1.10/192.168.1.20,并得到DNS 服务器192.168.1.1 3. DNS获取 手机 开始上网 浏览器输入www.google.com 互联网访问时基于IP地址的,这个时候需要获取www.google.com对应的真实IP地址。 手机检查本地系统DNS缓存有没有google的历史记录,如果没有,就向 自己的家庭路由器 192.168.1.1 这个IP地址发送DNS 请求查询(请告诉我 google的IP) , 家庭路由器 看看自己的DNS缓存有没有,如果没有,就向电信的DNS服务器 114.114.114.114 查询(请告诉我 google的IP), 如果电信DNS也没有,即向国际顶级DNS 服务器8.8.8.8(备注: 8.8.8.8实际是google的DNS服务器,这里只是举例), 只要开通了DNS注册,交钱的国际企业在 顶级域名是有记录的(除非只在某个范围内生效)。 最终手机就可以获取到www.google.com IP地址是图中9.9.9.20。 那么手机就可以将 192.168.1.1 发给 9.9.9.20 的http报文发送出去。 4 .报文通过路由器转发 手机 访问 9.9.9.20(google)的http报文 , 手机 à 家庭路由器 源IP地址是192.168.1.10 ,目的IP地址是9.9.9.20 ; 这里有个问题: 别人家也有一个192.168.1.10,那么google的服务器怎么知道是谁家的 192.168.1.10? 数据在互联网上传输,肯定是需要一个唯一的IP地址,那么对每家来说,唯一的IP地址是电信分配的。也就是说,每家只能用自己的IP地址作为源IP地址。 那么我家里有多台手机和电脑,怎么办? 手机1 192.168.1.10: 789 à 9.9.9.20: 80 被家庭路由器SNAT 成 201.1.1.10: 123à 9.9.9.20: 80 电脑1 192.168.1.20: 678 à 9.9.9.20: 80被家庭路由器SNAT 成 201.1.1.10: 124à 9.9.9.20: 80 也就是说,数据出了自己的路由器,整个过程源IP地址、目的IP地址、源端口号、目的端口号都是不变的,直到到达google, google返程 分别回给201.1.1.10:123和201.1.1.20:124 数据到达家庭路由器后,重新把目的IP地址换回192.168.1.10和192.168.1.20。最终完成数据的传输过程。 3 TCPIP学习3.1 ARP学习基础3.1.1 ARP报文以太网是根据MAC地址识别的。 PC1 学习到了PC3 的MAC地址,才可以发送报文,否则无法ping通,比如把 PC3移除。 192.168.2.1 向 192.168.2.3 发送 ARP报文,根据ARP的报文格式 类型 0x0800表示 ARP报文 。 发送ARP请求,只知道 自己的MAC地址,自己的IP地址, 对方的IP地址,但是不知道对方的MAC地址。 相当于 我要找人,这个人在我视线范围,但是我不认识他。那么我喊一下(广播),让所有的人都能听到。 目的MAC地址填 ff-ff-ff-ff-ff-ff 。 所有收到的人 判断一下是不是自己的IP地址,如果是自己的IP地址,那么就单播应答一下。 这样一来,双方都能知道对方的MAC地址。 记录到内存里面。因为下一个使用的时候不需要重新发送报文,提高效率。 但是如果一直不再给对方发送数据,也不知道对方还在不再。那么又存在浪费内存的情况。最好的方式是设置一个超时时间,默认20分钟。 如果20分钟到了,再重新发送一次,如果能学习到,说明还在,继续保留这个表象。 在Windows7上 运行 开始 cmd 输入 arp –a 可以观察到这个表项 Hub组网, PC1 ping PC3 ,在 PC2上可以抓到所有报文 但是把HUB换成交换机, PC1 ping PC3, 在PC2上只能抓到ARP请求报文(确切说是广播报文) 为什么? 3.1.3 路由器组网下的ARP学习组网如图,启动三个设备 双击 路由器 给路由器配置IP地址 <Huawei>sys [Huawei]interface Ethernet 0/0/0 [Huawei-Ethernet0/0/0]ip address 192.168.1.1 24 [Huawei-Ethernet0/0/0]q [Huawei]interface ethernet0/0/1 [Huawei-Ethernet0/0/1]ip address 192.168.2.1 24 在PC1 192.168.1.10 上ping PC2 192.168.2.20 如果没有路由器, PC1和PC2是不同网段, 是ping 不通的。如果换成交换机或者HUB,也是ping 不通的。 跨网段必须需要一个路由器来转发(备注:这里的交换机指二层交换机,三层交换机具备路由器的特征,可以三层转发; 二层表示是同一个网段) 观察,为什么PC1 没有PC2的MAC地址? 而只有路由器192.168.1.1的MAC地址? 3.2 观察windows 上的路由表3.3路由的选路过程4 socket编程(python)Server.py Client.py |
|