网络通信 Python Socket UDP Select

前言

工作中遇到各种各样的网络通信。有MQTT和CoAP这样的物联网应用层协议,也有各种自定义的TCP或UDP协议。使用各种不同的计算机语言和框架开发网络通信,例如Java的Netty框架,C语言原始socket,Python Socket。各有各的使用场景,难易程度相差巨大。Netty上手困难,C语言编写复杂,Python Socket上手容易。
长久以来,UDP通信一直被误解为一种不可靠的通信手段,但是UDP简单使用,特别适合物联网终端。UDP没有三次握手和四次挥手,换个角度来说节约了网络流量,降低了设备的功耗。UDP协议也是物联网应用层协议CoAP、LwM2M的传输层协议,也有消息说HTTP 3.0协议将使用UDP作为传输层协议

示例简述

  • 本例通过select实现一个UDP Server,一般来说select相比其他recv和send等常用函数难用不少,网上也很难找到合适的示例,特别是UDP Select示例。
  • 开发环境 Windows PyCharm社区版 Python3.7

服务器示例

udp-server-select.py

import select
import socket
import binascii

HOST = ''
PORT = 50018

server_fd = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_fd.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

server_fd.bind((HOST, PORT))
print('starting up on %s port %s' % (HOST, PORT))

# 把服务器套接字加入到输入列表中
inputs = [server_fd]
client_address = None
conn = None

while True:
    # readable, writable, exceptional = select.select(inputs, [], [], 1.0)
    readable = select.select(inputs, [], [], 1.0)[0]
    for s in readable:
        data, client_address = s.recvfrom(1024)
        if data:
            # 收到客户端数据
            print('received "%s" from %s' % (binascii.hexlify(data), client_address))
            s.sendto(data, client_address)

代码说明

  • inputs = [server_fd] 创建套接字后把服务器套接字加入到输入列表中
  • select函数有4个输入参数,分别为输入列表、输出列表、错误列表和超时时间,输出参数为一个Python元组类型,分别为可读列表、可写列表和错误列表。select函数原型如下:
    select(rlist, wlist, xlist[, timeout]) -> (rlist, wlist, xlist)
  • 如果仅需要查询可读列表,可以简写为select.select(inputs, [], [], 1.0)[0],也就是选择select返回元组类型的第0个元素。

客户端示例

请参考【网络通信 Python Socket UDP】

运行与测试

先启动UDP服务器,再启动UDP客户端。

服务器控制台可能输出

connected by ('127.0.0.1', 50019) received  b'31323334'
connected by ('192.168.3.18', 50019) received  b'31323334'

客户端控制台可能输出

received b'31323334' from ('127.0.0.1', 50018)

相关资料

  • 本例代码仓库【 python-socket-demo】
  • 物联网图书推荐 CoAP基础 徐凯《IoT开发实战: CoAP卷》 2017 机械工业出版社【 京东链接】
  • 物联网图书推荐 CoAPs进阶 徐凯 崔红鹏《密码技术与物联网安全:mbedtls开发实战》2019 机械工业出版社 【京东链接】

你可能感兴趣的:(网络通信 Python Socket UDP Select)