• 【Python】使用python通过TCP或UDP,实现收发报文数据


    1. socket 模块

    socket 又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

    可以通过socket() 函数来创建套接字对象:

    • socket.socket(socket.AF_INET, socket.SOCK_STREAM):创建socket对象,走TCP通道
    • socket.socket(socket.AF_INET, socket.SOCK_DGRAM):创建socket对象,走UDP通道

    socket对象的方法:

    1.tcp相关的方法

    方法描述
    listen()开始TCP监听,设置操作系统可以挂起的最大连接数量
    accept()被动接受TCP客户端连接,(阻塞式)等待连接的到来
    connect()主动初始化TCP服务器连接
    send()发送TCP数据,发送的数据为bytes类型
    recv()接收TCP数据,返回的数据为bytes类型

    2.udp相关的方法

    方法描述
    sendto()发送UDP数据,发送的数据为bytes类型,并指定发送的地址(ip, port)
    recvfrom()接收UDP数据,返回值是(data,address),address就是(ip, port)

    3.公共方法

    方法描述
    bind()绑定地址(ip,port)到套接字, 在AF_INET下,以元组(ip,port)的形式表示地址
    close()关闭套接字
    getpeername()返回连接套接字的远程地址,返回值通常是元组(ip,port)
    getsockname()返回套接字自己的地址,返回值通常是元组(ip,port)
    settimeout(timeout)设置套接字操作的超时期,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作,如connect()
    gettimeout()返回当前超时期的值

    2. 通过TCP收发报文

    1.新建文件tcp_server.py,用于模拟server端。

    import socket
    
    tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建socket对象,走tcp通道
    host = socket.gethostname() # 获取本地主机名
    port = 1000 # 端口号
    addr = (host, port)
    tcpServer.bind(addr) # 绑定地址
    tcpServer.listen(5) # 设置最大连接数,超过后排队
    
    while True:
        conn,addr = tcpServer.accept() # 建立客户端连接
        print(conn)
        data = conn.recv(1024) # 接收来自客户端的数据,小于1024字节
        print(data)
        msg = 'Hello Client'.encode('utf-8')
        conn.send(msg) # 发送数据给客户端
        conn.close() # 关闭连接
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    1. 本地主机名也可以换成IP地址,如host = '192.168.1.100'
    2. server 端需要一直运行,等待 client 端的连接,所以使用while True无限循环
    3. 发送的数据必须是bytes类型,所以字符串需要编码'Hello Client'.encode('utf-8'),编码后为bytes类型

    2.新建文件tcp_client.py,用于模拟client端。

    import socket               
     
    tcpClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建socket对象
    host = socket.gethostname() 
    port = 1000 
    addr = (host, port)
    tcpClient.connect(addr) # 连接服务,指定主机和端口号
    data = b'\x01\x64\xff' # 报文数据,bytes类型
    tcpClient.send(data) # 发送数据给服务端
    msg = tcpClient.recv(1024) # 接收来自服务端的数据,小于1024字节
    print(msg.decode('utf-8'))
    tcpClient.close()
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    client 端的地址需与 server 端一致,否则会报错:

    • IP地址不一致,则会发送数据给其他服务器,可能会出现报错TimeoutError
    • 端口号不一致,会出现报错ConnectionRefusedError

    3.打开两个cmd窗口,一个为server端窗口,另一个为client端窗口。

    运行顺序,先启动server,后启动client:

    • server端窗口,先执行命令 python tcp_server.py
    • client端窗口,后执行命令 python tcp_client.py

    运行结果如下:

    server端窗口:

    在这里插入图片描述

    client端窗口:

    在这里插入图片描述

    注:可以看到server端打印的报文为b'\x01d\xff',看上去与client端发送报文b'\x01\x64\xff'不一致,实际上是一致的。
    \x01d中的d为ASCII码,d对应的16进制的ASCII码正好是64,也就是说\x01d其实就是\x01\x64的缩写而已。

    运行如下代码,可以看到两者报文的长度和内容都是一致的:

    clientData =  b'\x01\x64\xff'
    serverData = b'\x01d\xff'
    print(list(clientData)) # [1, 100, 255]
    print(list(serverData)) # [1, 100, 255]
    
    • 1
    • 2
    • 3
    • 4

    3. 通过UDP收发报文

    1.新建文件udp_server.py,用于模拟server端。

    import socket
    
    udpServer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建socket对象,走udp通道
    host = socket.gethostname() # 获取本地主机名
    port = 1000
    serverAddr = (host, port)
    udpServer.bind(serverAddr) # 绑定服务端地址
    
    while True:
        clientData,clientAddr = udpServer.recvfrom(1024) # 接收来自客户端的数据
        print(clientData,clientAddr)
        msg = 'Hello Client'.encode('utf-8')
        udpServer.sendto(msg, clientAddr) # 发送数据给客户端
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.新建文件udp_client.py,用于模拟client端。

    import socket
    
    udpClient = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 创建socket对象,走udp通道
    host = socket.gethostname() # 获取本地主机名
    port = 1000
    serverAddr = (host, port)
    
    data = b'\x01\x64\xff' # 报文数据,bytes类型
    udpClient.sendto(data, serverAddr) # 发送数据给服务端
    serverData,serverAddr = udpClient.recvfrom(1024) # 接收来自服务端的数据
    print(serverData.decode('utf-8'), serverAddr)
    udpClient.close()
        
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.打开两个cmd窗口,一个为server端窗口,另一个为client端窗口。

    运行顺序,先启动server,后启动client:

    • server端窗口,先执行命令 python udp_server.py
    • client端窗口,后执行命令 python udp_client.py

    运行结果如下:

    server端窗口:

    在这里插入图片描述

    client端窗口:

    在这里插入图片描述

  • 相关阅读:
    JTAG 详解
    Python与CAD系列基础篇(六)创建块
    【JavaScript】Web API基础(五)
    【开源】基于SpringBoot的农村物流配送系统的设计和实现
    基于SSM的小区物业管理系统设计与实现
    [免费专栏] Android安全之Linux+Windows安装r2Frida环境配置及使用
    《Greenplum构建实时数据仓库实践》简介
    【科技1】
    2个表差分的比较
    opencv+vs2017配置
  • 原文地址:https://blog.csdn.net/aidijava/article/details/127587892