注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
我爱下载的个人空间 https://home.eeworld.com.cn/space-uid-101026.html [收藏] [复制] [分享] [RSS]
日志

【得捷电子Follow me第4期】基础任务二:TCP服务器和UDP服务器

已有 535 次阅读2024-2-6 13:52 |个人分类:产品评测

【得捷电子Follow me4期】基础任务TCP服务器UDP服务器

硬件环境

基于入门任务的硬件基本环境构建了一个可以连接网络的局域网,局域网内有一台PC和W5500-EVB-Pico设备。

 

图1 网络架构

软件实现

采用基础任务一的软件为基础,完成TCP和UDP服务器,服务器IP = 172.17.100.101,端口号Port = 40001 。

创建TCP服务器

利用adafruit_wiznet5k_socket库,创建一个TCP服务器。函数输入参数为服务器端口。
def create_tcpserver(port):
    # Initialize a socket for our server
    socket.set_interface(eth)
    sc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # Allocate socket for the server
    sc_ip = None  # IP address of server
    sc_port = port  # Port to listen on
    sc.bind((sc_ip, sc_port))  # Bind to IP and Port
    sc.listen()  # Begin listening for incoming clients
    
    return sc

 

创建UDP服务器

利用adafruit_wiznet5k_socket库,创建一个UDP服务器。函数输入参数为服务器端口。
def create_udpserver(port):
    # Initialize a socket for our server
    socket.set_interface(eth)
    sc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # Allocate socket for the server
    sc_port = port  # Port to listen on
    sc.bind((eth.pretty_ip(eth.ip_address), sc_port))  # Bind to IP and Port
    
    return sc

 

接收信息显示

当完成TCP服务器后,接收到的信息会显示到LCD显示器上,显示分为三个区域:
区域1:以太网参数区
区域2:TCP连接信息显示区
区域3:接收到的信息显示区
显示函数的输入参数为待显示的字符串和显示的位置。
def disp_str(s, addr):
    display.fill_rect(0,addr,144,10,1)
    display.text(s, 0, addr, 0)
    display.show()

 

完整实现

# 测试基础任务二

import time
import board
import busio
import digitalio
import array
import struct

import adafruit_sharpmemorydisplay
from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K
import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket

IP_ADDRESS = (172, 17, 100, 101)
SUBNET_MASK = (255, 255, 0, 0)
GATEWAY_ADDRESS = (172, 17, 64, 1)
DNS_SERVER = (218, 203, 59, 116)


def init():
    led = digitalio.DigitalInOut(board.GP25)
    led.direction = digitalio.Direction.OUTPUT

    # Initialize SPI bus and control pins
    spi = busio.SPI(board.GP14, MOSI=board.GP15)
    scs = digitalio.DigitalInOut(board.GP13)  # inverted chip select

    # pass in the display size, width and height, as well
    # display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 96, 96)
    display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 144, 168)
    
    return led,display

def led_flush():
    led.value = not led.value
    time.sleep(0.5)

def clear_disp():
    # Clear the display.  Always call show after changing pixels to make the display
    # update visible!
    display.fill(1)
    display.show()

def disp_helloworld():
    print("hello world")
    display.fill(1)
    display.text(" hello world!", 30, 50, 0)
    display.show()

def init_w5500(ip, subnet, gateway, dns):
    ##SPI0
    SPI0_SCK = board.GP18
    SPI0_TX = board.GP19
    SPI0_RX = board.GP16
    SPI0_CSn = board.GP17    
    ##reset
    W5x00_RSTn = board.GP20
    
    print("Wiznet5k Ping Test (no DHCP)")
    
    ethernetRst = digitalio.DigitalInOut(W5x00_RSTn)
    ethernetRst.direction = digitalio.Direction.OUTPUT
    
    # For Adafruit Ethernet FeatherWing
    cs = digitalio.DigitalInOut(SPI0_CSn)
    # For Particle Ethernet FeatherWing
    # cs = digitalio.DigitalInOut(board.D5)
    spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX)
    
    # Reset W5500 first
    ethernetRst.value = False
    time.sleep(1)
    ethernetRst.value = True

    # Initialize ethernet interface without DHCP
    eth = WIZNET5K(spi_bus, cs, is_dhcp=False)

    # Set network configuration
    eth.ifconfig = (ip, subnet, gateway, dns)

    print("Chip Version:", eth.chip)
    print("My IP address is:", eth.pretty_ip(eth.ip_address))

    return eth

def disp_w5500():
    clear_disp()
    display.fill(1)
    cst = "chip version:" + eth.chip
    display.text(cst, 0, 0, 0)
    cst = "ip:" + eth.pretty_ip(eth.ip_address)
    display.text(cst, 0, 10, 0)
    cst = "mac:" + eth.pretty_mac(eth.mac_address)
    display.text(cst, 0, 20, 0)
    display.show()

def disp_str(s, addr):
    display.fill_rect(0,addr,144,10,1)
    display.text(s, 0, addr, 0)
    display.show()
    

def inCksum(packet):
    if len(packet) & 1:
        packet = packet + '\0'
    words = array.array('h', packet)
    sum = 0
    for word in words:
        sum += (word & 0xffff)
    sum = (sum>>16) + (sum & 0xffff)
    sum = sum + (sum >> 16)
    return (~sum) & 0xffff

def create_tcpserver(port):
    # Initialize a socket for our server
    socket.set_interface(eth)
    sc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # Allocate socket for the server
    sc_ip = None  # IP address of server
    sc_port = port  # Port to listen on
    sc.bind((sc_ip, sc_port))  # Bind to IP and Port
    sc.listen()  # Begin listening for incoming clients
    
    return sc

def create_udpserver(port):
    # Initialize a socket for our server
    socket.set_interface(eth)
    sc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # Allocate socket for the server
#    sc_ip = None  # IP address of server
    sc_port = port  # Port to listen on
    sc.bind((eth.pretty_ip(eth.ip_address), sc_port))  # Bind to IP and Port
    
    return sc


if __name__ == '__main__':
    # 初始化led和显示模块
    led,display = init()
    clear_disp()
    #静态初始化w5500
    eth = init_w5500(IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER)
    disp_w5500()
    
    # 创建一个tcp服务器
#    server = create_tcpserver(40001)
    # 创建一个udp服务器
    server = create_udpserver(40001)
    
#    conn, addr = server.accept()  # Wait for a connection from a client.
    print("socket connected")
#    print(addr)
    disp_str("UDP Server TEST", 30)
    disp_str("socket connected", 40)
#    disp_str('cli:'+addr[0]+','+str(addr[1]), 50)
    disp_str('receive:', 60)
    linenum = 70
    while True:
        led_flush()
        
        with server:
            while True:
#                data = conn.recv(20)
                data,addr = server.recvfrom(20)
                disp_str('cli:'+addr[0]+','+str(addr[1]), 50)
                if data:
                    print(data)
                    disp_str(data.decode('utf-8'),linenum)
                    linenum += 10
                    if linenum > 150:
                        linenum = 70
#                    conn.send(data)  # Echo message back to client


 

运行输出

TCP服务器运行

 

TCP数据抓包分析

利用wirshark抓取网络数据帧,并解析。

 

TCP数据分析
No.     Time           Source                Destination           Protocol Length Info
     82 0.439476       172.17.64.61          172.17.100.101        TCP      65     1000 → 40001 [PSH, ACK] Seq=1 Ack=1 Win=64240 Len=11

Frame 82: 65 bytes on wire (520 bits), 65 bytes captured (520 bits) on interface \Device\NPF_{CFD99493-9F53-4E3C-9055-F0CD9D70A623}, id 0
Ethernet II, Src: Dell_1e:6f:59 (50:9a:4c:1e:6f:59), Dst: de:ad:be:ef:fe:ed (de:ad:be:ef:fe:ed)
Internet Protocol Version 4, Src: 172.17.64.61, Dst: 172.17.100.101
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
    Total Length: 51
    Identification: 0x4e8c (20108)
    Flags: 0x40, Don't fragment
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 128
    Protocol: TCP (6)
    Header Checksum: 0x0000 [validation disabled]
    [Header checksum status: Unverified]
    Source Address: 172.17.64.61
    Destination Address: 172.17.100.101
Transmission Control Protocol, Src Port: 1000, Dst Port: 40001, Seq: 1, Ack: 1, Len: 11
    Source Port: 1000
    Destination Port: 40001
    [Stream index: 0]
    [Conversation completeness: Incomplete (12)]
    [TCP Segment Len: 11]
    Sequence Number: 1    (relative sequence number)
    Sequence Number (raw): 1159226630
    [Next Sequence Number: 12    (relative sequence number)]
    Acknowledgment Number: 1    (relative ack number)
    Acknowledgment number (raw): 606290203
    0101 .... = Header Length: 20 bytes (5)
    Flags: 0x018 (PSH, ACK)
    Window: 64240
    [Calculated window size: 64240]
    [Window size scaling factor: -1 (unknown)]
    Checksum: 0xfcea [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    [Timestamps]
    [SEQ/ACK analysis]
    TCP payload (11 bytes)
Data (11 bytes)

0000  68 65 6c 6c 6f 20 77 6f 72 31 64                  hello wor1d
    Data: 68656c6c6f20776f723164
[Length: 11]

 

UDP服务器运行

 

UDP数据抓包分析

UDP数据分析

No.     Time           Source                Destination           Protocol Length Info
    711 0.696170       172.17.64.61          172.17.100.101        UDP      51     80 → 40001 Len=9

Frame 711: 51 bytes on wire (408 bits), 51 bytes captured (408 bits) on interface \Device\NPF_{CFD99493-9F53-4E3C-9055-F0CD9D70A623}, id 0
    Interface id: 0 (\Device\NPF_{CFD99493-9F53-4E3C-9055-F0CD9D70A623})
    Encapsulation type: Ethernet (1)
    Arrival Time: Feb  6, 2024 13:32:18.559318000 中国标准时间
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1707197538.559318000 seconds
    [Time delta from previous captured frame: 0.005620000 seconds]
    [Time delta from previous displayed frame: 0.000000000 seconds]
    [Time since reference or first frame: 0.696170000 seconds]
    Frame Number: 711
    Frame Length: 51 bytes (408 bits)
    Capture Length: 51 bytes (408 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:udp:data]
    [Coloring Rule Name: UDP]
    [Coloring Rule String: udp]
Ethernet II, Src: Dell_1e:6f:59 (50:9a:4c:1e:6f:59), Dst: de:ad:be:ef:fe:ed (de:ad:be:ef:fe:ed)
    Destination: de:ad:be:ef:fe:ed (de:ad:be:ef:fe:ed)
    Source: Dell_1e:6f:59 (50:9a:4c:1e:6f:59)
    Type: IPv4 (0x0800)
Internet Protocol Version 4, Src: 172.17.64.61, Dst: 172.17.100.101
    0100 .... = Version: 4
    .... 0101 = Header Length: 20 bytes (5)
    Differentiated Services Field: 0x00 (DSCP: CS0, ECN: Not-ECT)
    Total Length: 37
    Identification: 0x4f1e (20254)
    Flags: 0x00
    ...0 0000 0000 0000 = Fragment Offset: 0
    Time to Live: 128
    Protocol: UDP (17)
    Header Checksum: 0x0000 [validation disabled]
    [Header checksum status: Unverified]
    Source Address: 172.17.64.61
    Destination Address: 172.17.100.101
User Datagram Protocol, Src Port: 80, Dst Port: 40001
    Source Port: 80
    Destination Port: 40001
    Length: 17
    Checksum: 0xfce7 [unverified]
    [Checksum Status: Unverified]
    [Stream index: 36]
    [Timestamps]
    UDP payload (9 bytes)
Data (9 bytes)

0000  68 65 6c 6c 6f 20 75 64 70                        hello udp
    Data: 68656c6c6f20756470
    [Length: 9]

 

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章