376|0

175

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

【得捷电子Follow me第4期】基础任务一(补充2):ping通站点并返回ICMP报文 [复制链接]

  本帖最后由 电子烂人 于 2024-2-24 19:45 编辑

有群友说之前的“基础任务一”其中的ping部分仅分析了DNS地址,没有返回完整的ICMP报文

这部分在原来的PING代码上借鉴了下StreakingJerry大佬重构的ping函数:

  • from machine import Pin,SPI,PWM
  • import usocket
  • import network
  • import framebuf
  • import time
  • BL = 13
  • DC = 8
  • RST = 12
  • MOSI = 11
  • SCK = 10
  • CS = 9
  • def w5x00_init():
  • spi=SPI(0,2_000_000, mosi=Pin(19),miso=Pin(16),sck=Pin(18))
  • nic = network.WIZNET5K(spi,Pin(17),Pin(20))
  • nic.active(True)
  • nic.ifconfig(('192.168.2.114','255.255.255.0','192.168.2.1','8.8.8.8'))
  • print('IP address :', nic.ifconfig())
  • while not nic.isconnected():
  • time.sleep(1)
  • #print(nic.regs())
  • return nic
  • def dns_query(domain):
  • ip = usocket.getaddrinfo(domain, 80,0, usocket.SOCK_STREAM)
  • return ip[0][4][0]
  • def checksum(data):
  • if len(data) & 0x1: # Odd number of bytes
  • data += b'\0'
  • cs = 0
  • for pos in range(0, len(data), 2):
  • b1 = data[pos]
  • b2 = data[pos + 1]
  • cs += (b1 << 8) + b2
  • while cs >= 0x10000:
  • cs = (cs & 0xffff) + (cs >> 16)
  • cs = ~cs & 0xffff
  • return cs
  • def ping(host, count=4, timeout=30, interval=1, quiet=False, size=64):
  • import time
  • import select
  • import uctypes
  • import socket
  • import struct
  • import random
  • # prepare packet
  • assert size >= 16, "pkt size too small"
  • pkt = b'Q'*size
  • pkt_desc = {
  • "type": uctypes.UINT8 | 0,
  • "code": uctypes.UINT8 | 1,
  • "checksum": uctypes.UINT16 | 2,
  • "id": uctypes.UINT16 | 4,
  • "seq": uctypes.INT16 | 6,
  • "timestamp": uctypes.UINT64 | 8,
  • } # packet header descriptor
  • h = uctypes.struct(uctypes.addressof(pkt), pkt_desc, uctypes.BIG_ENDIAN)
  • h.type = 8 # ICMP_ECHO_REQUEST
  • h.code = 0
  • h.checksum = 0
  • h.id = random.getrandbits(16)
  • h.seq = 1
  • # init socket
  • sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, 1)
  • sock.setblocking(0)
  • sock.settimeout(timeout/1000)
  • c = 0
  • addr = None
  • while c < 10:
  • try:
  • c += 1
  • time.sleep_ms(100)
  • addr = socket.getaddrinfo(host, 1)[0][-1][0] # ip address
  • break
  • except:
  • pass
  • if not addr:
  • print("DNS lookup failed")
  • return
  • sock.connect((addr, 1))
  • not quiet and print("PING %s (%s): %u data bytes" % (host, addr, len(pkt)))
  • seqs = list(range(1, count+1)) # [1,2,...,count]
  • c = 1
  • t = time.time()
  • tstart = time.time()
  • n_trans = 0
  • n_recv = 0
  • finish = False
  • while time.time() - tstart < timeout:
  • if time.time() - t >= interval and c<=count:
  • # send packet
  • h.checksum = 0
  • h.seq = c
  • h.timestamp = time.ticks_us()
  • h.checksum = checksum(pkt)
  • if sock.send(pkt) == size:
  • n_trans += 1
  • t = time.time() # reset timeout
  • else:
  • seqs.remove(c)
  • # recv packet
  • socks, _, _ = select.select([sock], [], [], 0)
  • if socks:
  • resp = socks[0].recv(4096)
  • resp_mv = memoryview(resp)
  • h2 = uctypes.struct(uctypes.addressof(resp_mv[20:]), pkt_desc, uctypes.BIG_ENDIAN)
  • # TODO: validate checksum (optional)
  • seq = h2.seq
  • if h2.type==0 and h2.id==h.id and (seq in seqs): # 0: ICMP_ECHO_REPLY
  • t_elasped = (time.ticks_us()-h2.timestamp) / 1000
  • ttl = struct.unpack('!B', resp_mv[8:9])[0] # time-to-live
  • n_recv += 1
  • c += 1
  • not quiet and print("%u bytes from %s: icmp_seq=%u, ttl=%u, time=%f ms" % (len(resp), addr, seq, ttl, t_elasped))
  • seqs.remove(seq)
  • if len(seqs) == 0:
  • finish = True
  • if finish:
  • break
  • # close
  • sock.close()
  • ret = (n_trans, n_recv)
  • not quiet and print("%u packets transmitted, %u packets received" % (n_trans, n_recv))
  • return (n_trans, n_recv)
  • class LCD_1inch14(framebuf.FrameBuffer):
  • def __init__(self):
  • self.width = 240
  • self.height = 135
  • self.cs = Pin(CS,Pin.OUT)
  • self.rst = Pin(RST,Pin.OUT)
  • self.cs(1)
  • self.spi = SPI(1)
  • self.spi = SPI(1,1000_000)
  • self.spi = SPI(1,10000_000,polarity=0, phase=0,sck=Pin(SCK),mosi=Pin(MOSI),miso=None)
  • self.dc = Pin(DC,Pin.OUT)
  • self.dc(1)
  • self.buffer = bytearray(self.height * self.width * 2)
  • super().__init__(self.buffer, self.width, self.height, framebuf.RGB565)
  • self.init_display()
  • self.red = 0x07E0
  • self.green = 0x001f
  • self.blue = 0xf800
  • self.white = 0xffff
  • def write_cmd(self, cmd):
  • self.cs(1)
  • self.dc(0)
  • self.cs(0)
  • self.spi.write(bytearray([cmd]))
  • self.cs(1)
  • def write_data(self, buf):
  • self.cs(1)
  • self.dc(1)
  • self.cs(0)
  • self.spi.write(bytearray([buf]))
  • self.cs(1)
  • def init_display(self):
  • """Initialize dispaly"""
  • self.rst(1)
  • self.rst(0)
  • self.rst(1)
  • self.write_cmd(0x36)
  • self.write_data(0x70)
  • self.write_cmd(0x3A)
  • self.write_data(0x05)
  • self.write_cmd(0xB2)
  • self.write_data(0x0C)
  • self.write_data(0x0C)
  • self.write_data(0x00)
  • self.write_data(0x33)
  • self.write_data(0x33)
  • self.write_cmd(0xB7)
  • self.write_data(0x35)
  • self.write_cmd(0xBB)
  • self.write_data(0x19)
  • self.write_cmd(0xC0)
  • self.write_data(0x2C)
  • self.write_cmd(0xC2)
  • self.write_data(0x01)
  • self.write_cmd(0xC3)
  • self.write_data(0x12)
  • self.write_cmd(0xC4)
  • self.write_data(0x20)
  • self.write_cmd(0xC6)
  • self.write_data(0x0F)
  • self.write_cmd(0xD0)
  • self.write_data(0xA4)
  • self.write_data(0xA1)
  • self.write_cmd(0xE0)
  • self.write_data(0xD0)
  • self.write_data(0x04)
  • self.write_data(0x0D)
  • self.write_data(0x11)
  • self.write_data(0x13)
  • self.write_data(0x2B)
  • self.write_data(0x3F)
  • self.write_data(0x54)
  • self.write_data(0x4C)
  • self.write_data(0x18)
  • self.write_data(0x0D)
  • self.write_data(0x0B)
  • self.write_data(0x1F)
  • self.write_data(0x23)
  • self.write_cmd(0xE1)
  • self.write_data(0xD0)
  • self.write_data(0x04)
  • self.write_data(0x0C)
  • self.write_data(0x11)
  • self.write_data(0x13)
  • self.write_data(0x2C)
  • self.write_data(0x3F)
  • self.write_data(0x44)
  • self.write_data(0x51)
  • self.write_data(0x2F)
  • self.write_data(0x1F)
  • self.write_data(0x1F)
  • self.write_data(0x20)
  • self.write_data(0x23)
  • self.write_cmd(0x21)
  • self.write_cmd(0x11)
  • self.write_cmd(0x29)
  • def show(self):
  • self.write_cmd(0x2A)
  • self.write_data(0x00)
  • self.write_data(0x28)
  • self.write_data(0x01)
  • self.write_data(0x17)
  • self.write_cmd(0x2B)
  • self.write_data(0x00)
  • self.write_data(0x35)
  • self.write_data(0x00)
  • self.write_data(0xBB)
  • self.write_cmd(0x2C)
  • self.cs(1)
  • self.dc(1)
  • self.cs(0)
  • self.spi.write(self.buffer)
  • self.cs(1)
  • if __name__=='__main__':
  • pwm = PWM(Pin(BL))
  • pwm.freq(1000)
  • pwm.duty_u16(32768)#max 65535
  • LCD = LCD_1inch14()
  • w5x00_init()
  • ip = dns_query("eeworld.com.cn")
  • gate = ip.split(".")
  • gate[-1] = "1"
  • gate = ".".join(gate)
  • ping(gate, quiet=True)
  • ping("eeworld.com.cn")
  • print("IP address is %s"%(ip))
  • while True:
  • LCD.fill(LCD.white)
  • LCD.text("Follow me NO.4",0,5,LCD.red)
  • LCD.text("Base_2 Task :",130,5,LCD.green)
  • LCD.hline(10,15,220,LCD.blue)
  • LCD.hline(10,115,220,LCD.blue)
  • LCD.vline(10,15,100,LCD.blue)
  • LCD.vline(230,15,100,LCD.blue)
  • LCD.text("ping running",15,20,LCD.green)
  • LCD.text('IP address :%s'%(ip),15,30,LCD.blue)
  • LCD.text("by ee_jark",120,120,LCD.blue)
  • LCD.show()
  • time.sleep(2)
  • LCD.show()
  • LCD.fill(0xFFFF)
  • # LCD.text("Follow me NO.4",20,20,LCD.red)
  • # LCD.text("Basic Task 1:",20,40,LCD.green)
  • # LCD.text("IP address is %s"%(ip),20,60,LCD.red)
  • # LCD.text("by ee_jark",20,80,LCD.blue)
  • # LCD.show()
  • #
  • # time.sleep(1)
  • # LCD.fill(0xFFFF)

烧录后的对话窗口会返回完整的PING命令的ICMP报文:

 

显示屏仍会返回对应的DNS地址

 

点赞 关注
个人签名

没用比没有强

 
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
福禄克有奖直播:高精度测温赋能电子制造 报名中!
直播时间:2025年2月28日(周五)上午10:00
直播主题:高精度测温赋能电子制造
小伙伴们儿快来报名直播吧~好礼等你拿!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表