python27期尚哥讲TFTP:

TFTP介绍 :
TFTP(Trivial File Transfer Protocol,简单⽂件传输协议)是TCP/IP协议簇中的⼀个⽤来在客户端与服务器之间进⾏简单⽂件传输的协议
使用tftp这个协议,就可以实现简单文件的下载
特点:
简单
占⽤资源⼩
适合传递⼩⽂件
适合在局域⽹进⾏传递
端⼝号为69
基于UDP实现

Tftpd32:共享服务器(可以从本机共享文件)

browse:选择一个文件夹,确定给客户端文件时的搜索路径

客户端:数据接收方
服务器:数据发送方

有了服务器之后,还需要编写一个下载器(客户端)
实现TFTP下载器:
下载:从服务器上将一个文件复制到本机上
下载的过程:
在本地创建一个空文件(与要下载的文件同名)
向里面写数据(接收到一点就向空文件里写一点)
关闭(接受完所有数据关闭文件)

注意:服务器的69端口只用来接收读写请求,ack包不要发到69端口

当客户端接收到的数据⼩于516(2字节操作码+2个字节的序号+512字节数据) 时, 就意味着服务器发送完毕了 (如果恰好最后一次数据长度为516,会再发一个长度为0的数据包)
构造下载请求数据:“1test.jpg0octet0”
import struct
cmb_buf = struct.pack(“!H8sb5sb”,1,b“test.jpg”,0,b“octet”,0)
如何保证操作码(1/2/3/4/5)占两个字节?如何保证0占一个字节?
#!H8sb5sb: ! 表示按照网络传输数据要求的形式来组织数据(占位的格式)
H 表示将后面的 1 替换成占两个字节
8s 相当于8个s(ssssssss)占8个字节
b 占一个字节

struct模块可以按照指定格式将Python数据转换为字符串,该字符串为字节流
struct模块中最重要的三个函数是pack()--包装, unpack()--打开, calcsize()
# 按照给定的格式(fmt),把数据封装成字符串(实际上是类似于c结构体的字节流)
pack(fmt, v1, v2, ...) 
# 按照给定的格式(fmt)解析字节流string,返回解析出来的元组
unpack(fmt, string) 
# 计算给定的格式(fmt)占用多少字节的内存
calcsize(fmt)

struct.pack(“!H8sb5sb”,1,“test.jpg”,0,“octet”,0)
struct.pack("!HH",4,p_num)
cmdTuple = struct.unpack("!HH", recvData[:4])

#TFTP客户端编程(下载):
#下载器:
#通信:
from socket import *
#打包:
import struct
addr = ("192.168.19.138",69)
pname = input("请输入要下载的文件名:")
#按照给定的格式(fmt),把数据封装成字符串
pack = struct.pack(f"!H{len(pname)}sb5sb",1,pname.encode(),0,b"octet",0)
#指定协议:
s = socket(AF_INET,SOCK_DGRAM)
#第一次发送, 连接服务器69端口:
s.sendto(pack,addr)
#a:以追加模式打开(必要时可以创建)append;b:表示二进制
f = open(pname,"ab")
while True:
#接收数据
data = s.recvfrom(1024)
print(data)
dizhi = data[1]
#按照给定的格式(fmt)解析字节流string,返回解析出来的元组
caozuoma,kuaibianhao = struct.unpack("!HH",data[0][:4]) #获取数据块编号
# print("操作码是:",caozuoma,"块编号是:",kuaibianhao)
if caozuoma == 3:
f.write(data[0][4:]) #将数据写入
if caozuoma == 5:
print("下载出错!")
break
ack = struct.pack("!HH",4,kuaibianhao)
s.sendto(ack,dizhi) #回复ACK确认包
if len(data[0]) < 516:
print("下载结束!")
break

TFTP客户端编程(上传):
import struct
from socket import *
filename = "狗2.jpg"
data = struct.pack(f"!H{len(filename.encode('gb2312'))}sb5sb",2,filename.encode("gb2312"),0,b"octet",0)
s = socket(type=SOCK_DGRAM)
s.sendto(data,("192.168.19.138",69))
f = open(filename,"rb")
while True:
ret = s.recvfrom(1024)
duankouhao = ret[1]
data1,data2 = struct.unpack("!HH",ret[0][:4])
if data1 == 4:
data = f.read(512)
dabao = struct.pack(f"!HH{len(data)}s",3,data2+1,data)
s.sendto(dabao,duankouhao)
if len(data) < 512:
break

udp广播:
当前网络上所有电脑的某个进程都收到同一个数据
(tcp没有广播)
单播:点对点
多播:一对多
广播:一对所有接收方 (飞秋知道有人上线了?
谁在线?IP地址分配)
如果让广播方给接收方每人发一份数据,将会出现卡顿。所以借助交换机来分发数据

import socket
dest = (‘<broadcast>’,7788) #<broadcast>自动识别当前网络的广播地址
#创建udp套接字
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#对这个需要发送广播数据的套接字进行修改设置,否则不能发送广播数据
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) #允许s发送广播数据
#setsocketopt 设置套接字选项
#以广播形式发送数据到本网络的所有电脑中
s.sendto(b'Hi',dest)
print("等待回复")
while True:
(buf, address) = s.recvfrom(2048)
print(address,buf.decode(“GB2312”))

Packet Tracer 介绍&安装:
Packet Tracer 是由Cisco(思科)公司发布的⼀个辅助学习⼯具,为学习思科⽹络课程的初学者去设计、
配置、 排除⽹络故障提供了⽹络模拟环境(不用买硬件)可以提供数据包在网络中行进的详细处理过程
观察网络实时运行情况 (辅助学习网络通信过程)

2台电脑连网:
添加两台电脑
连接
设置网络
ping

单击终端设备,分别设置两台终端的IP和子网掩码
子网掩码:与IP成对出现,进行按位与操作后可以得到当前的网络号(哪类IP)

再单击其中一台终端,尝试IP地址能否ping通 (换一个网段还能否ping通?)

添加三台电脑
添加集线器 (为什么不能连到之前的通路上?)
连网
设置网络
ping

通过集线器连网:
集线器类似于USB扩展口:用来链接多台电脑

通过交换机连网:
集线器(HUB)是计算机网络中连接多个计算机或其他设备的连接设备,是对网络进行集中管理的最小单元。
英文Hub就是中心的意思,像树的主干一样,它是各分支的汇集点。HUB是一个共享设备,
主要提供信号放大和中转的功能,它把一个端口接收的所有信号向所有端口分发出去。
交换机(Switch)是一种基于MAC(网卡的硬件地址)识别,能完成封装转发数据包功能的网络设备。
交换机可以“学习”MAC地址,并把其存放在内部地址表中,通过在数据帧的始发者和目标接收者之间建立临时的交换路径,
使数据帧直接由源地址到达目的地址

例如一个8口hub, 当端口1上的机器要给端口8上的机器发数据
端口1上hub上有没有数据在传输,如果没有,端口1就跳出来向hub上喊:“我有数据包要给端口8,请端口8听到后回话”
这个数据被以广播的方式发送到hub上的其余7个口上,每端口都会接到这样的数据包,然后端口2---端口7会发一则消息给1:“我不是端口8”
与此同时端口8会发消息给1:“我是端口8,找我吗?”端口1收到上述消息后,会和端口8进行确认,然后他们建立传输链接,完成数据转发。
等如果端口1在发送寻找断口8的消息后,没有得到相应,那它还会接着发这个消息,直到收到端口8的回答。
等端口1和端口8完整数据转发后,假设他们还要进行通讯,那么hub上还会重复以上的过程。
一个数据,需要送达所有的端口,这不但增加了数据转发的时间,而且hub往往会给网络带来广播风暴(广播数据充斥网络无法处理,并占用大量网络带宽,导致正常业务不能运行)

相同的工作交换机就不用这么麻烦
假设端口1和端口8从没有通信过,那么开始的时候,他们的工作和hub一样,端口1要在交换机上找端口8,一旦端口8返回确认信息,那再端口1上就会生成1个和端口8的地址对应表
这个表里面有所有和端口1通过信的端口,一旦有了这地址对应表,那在以后端口1要和端口8通讯,可以直接送达,而且其他的端口也不会知道他们之间正在转发数据,这样加快了数据转发时间,并且避免了广播风暴 (ping之后点模拟测试以上规则)

通过路由器连网:
两台电脑之间能通信的前提是什么?
在同一网段
多台电脑之间为什么不能把网线剪开连在一起?
数据是通过电信号来传输的,多个电信号同时传输会出错
集线器hub有什么作用?
链接多台电脑组成小型局域网
集线器和交换机的区别?
集线器收到的所有数据包都会以广播形式发送
交换机可以智能学习,如果已经通信过的设备之间,可以直接通信

物理地址(实际地址):由网络设备制造商生产时写在硬件内部
IP地址与MAC地址在计算机里都是以二进制表示的,IP地址是32位的,而MAC地址则是48位的(6个字节)
如:08:00:20:0A:8C:6D就是一个MAC地址,其中前3组16进制数08:00:20代表网络硬件制造商的编号,
它由IEEE(电气与电子工程师协会)分配而后3组16进制数0A:8C:6D代表该制造商所制造的某个网络产品(如网卡)的系列号

MAC地址在世界是惟一的
(可以直接理解为网卡的序列号)
通过IP地址、端口号、MAC地址 保证了数据的稳定传输

路由器:确定一条路径的设备,路由器是连接因特网中用来链接网络号不同的、不同的网络,相当于中间人各局域网、广域网的设备,它会根据信道的情况自动选择和设定路由,以最佳路径,按前后顺序发送信号的设备。
路由器的一个作用是连通不同的网络,另一个作用是选择信息传送的线路
选择通畅快捷的近路,能大大提高通信速度,减轻网络系统通信负荷,节约网络系统资源,提高网络系统畅通率(举例:怎么去柏林)

同一个局域网当中的终端之间进行通讯的基础是处于同一个网段中,一个路由器至少有两个网卡,能够链接不同网段的网络使之可以通信(了解即可)

猜你喜欢

转载自www.cnblogs.com/zhang-da/p/11900465.html