Python 封装 socket 为 [TCP/UDP/MULTICAST] 客户端

news/2024/10/3 15:39:58/

发送 TCP/UDP/MULTICAST 数据并接收响应。

python">#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socketclass ClientSocket:def __init__(self, *, protocol: str, ip: str, port: int, recv_timeout: float = 1.5):"""客户端套接字发送 TCP/UDP/MULTICAST 数据并接收响应。Args:protocol (str): 协议ip (str): ip 地址port (int): 端口号recv_timeout (float, optional): 接收超时时间. Defaults to 1.5.Raises:ValueError: 无效的端口号, 应为 [1-65535]ValueError: 无效的协议类型, 应为 [TCP, UDP, MULTICAST]"""if port < 1 or port > 65535:raise ValueError(f'ServerSocket 无效的端口号 "{port}"')if protocol not in ['TCP', 'UDP', 'MULTICAST']:raise ValueError(f'ServerSocket 无效的协议类型 "{protocol}"')self.protocol = protocolself.ip = ipself.port = portself.recv_timeout = recv_timeoutself.sock: socket.socket | None = Noneself.__connected = Falsedef __str__(self) -> str:return f"ClientSocket({self.ip}:{self.port})"def connect(self) -> bool:if not self.__connected:try:match self.protocol:case 'TCP':self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.sock.connect((self.ip, self.port))case 'UDP':self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)if self.ip.endswith('.255'): # 设置 SO_BROADCAST 为 1, 允许发送广播数据包self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)case 'MULTICAST':self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 2)self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_LOOP, 1)self.sock.bind(('', self.port))self.sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton(self.ip) + socket.inet_aton('0.0.0.0'))self.sock.settimeout(self.recv_timeout)self.__connected = Trueexcept ConnectionRefusedError:print(f'{self} 无法连接: {self.ip}:{self.port}')except Exception as e:print(f'{self} 创建失败: {e}')return self.__connecteddef send(self, data: bytes) -> None:try:print(f'{self} 发送数据: {data}')if self.protocol == 'TCP':self.sock.sendall(data)else:self.sock.sendto(data, (self.ip, self.port))except OSError as e:if e.errno == 10057:print(f'{self} 发送失败连接未建立')else:print(f'{self} 发送失败: {e}')def recv(self) -> bytes | None:try:data, _ = self.sock.recvfrom(1024)print(f'{self} 收到数据: {data}')return dataexcept TimeoutError:return Noneexcept OSError as e:if e.errno == 10057:print(f'{self} 接收失败连接未建立')else:print(f'{self} 接收失败: {e}')def close(self) -> bool:if self.__connected:try:self.sock.shutdown(socket.SHUT_RDWR)self.sock.close()self.__connected = Falseexcept Exception as e:print(f'{self} 关闭失败: {e}')return not self.__connectedif __name__ == '__main__':from time import sleep# client = ClientSocket(protocol='TCP', ip='127.0.0.1', port=60000)# client = ClientSocket(protocol='UDP', ip='127.0.0.1', port=60000)client = ClientSocket(protocol='MULTICAST', ip='224.1.1.1', port=65000)client.connect()times = 3while times > 0:times -= 1client.send(b'hello')client.recv()sleep(1)client.send(b'q')client.recv()client.close()

http://www.ppmy.cn/news/1533981.html

相关文章

【嵌入式裸机开发】智能家居入门3(MQTT服务器、MQTT协议、微信小程序、STM32)

前面已经写了两篇博客关于智能家居的&#xff0c;服务器全都是使用ONENET中国移动&#xff0c;他最大的优点就是作为数据收发的中转站是免费的。本篇使用专门适配MQTT协议的MQTT服务器&#xff0c;有公用的&#xff0c;也可以自己搭建 前言一、项目总览二、总体流程分析1、了解…

python 实现md5算法

md5算法介绍 MD5&#xff08;Message-Digest Algorithm 5&#xff09;是一种广泛使用的加密散列函数&#xff0c;由Ronald Rivest于1991年设计&#xff0c;并在1992年正式发布。MD5可以将任意长度的“消息”&#xff08;也可以是文件&#xff09;计算出一个固定长度的“摘要”…

RabbitMQ 延迟消息

基本概念&#xff1a; 生产者发送消息时指定一个时间&#xff0c;消费者不会立刻收到消息&#xff0c;而是在指定时间之后才收到消息。 死信&#xff1a; 指那些无法被正常路由到队列的消息&#xff0c;或者在队列中无法被消费者正常消费的消息。当消息满足某些特定条件时&am…

音视频入门基础:FLV专题(7)——Tag header简介

一、引言 从《音视频入门基础&#xff1a;FLV专题&#xff08;3&#xff09;——FLV header简介》中可以知道&#xff0c; 在FLV header之后&#xff0c;FLV文件剩下的部分应由PreviousTagSize和Tag组成。FLV文件 FLV header PreviousTagSize0 Tag1 PreviousTagSize1 Ta…

SAP_FI_主数据和业务数据

在SAP的FI&#xff08;Financial Accounting&#xff09;模块中&#xff0c;主数据和业务数据是两个关键的组成部分。它们各自有着不同的定义和用途&#xff1a; 主数据 (Master Data) 主数据是指系统中较为静态且相对长期使用的数据&#xff0c;通常能够跨多个财务周期使用。…

相机、镜头参数详解以及相关计算公式

一、工业相机参数 1、分辨率 相机每次采集图像的像素点数&#xff0c;也是指这个相机总共有多少个感光晶片。在采集图像时&#xff0c;相机的分辨率对检测精度有很大的影响&#xff0c;在对同样打的视场成像时&#xff0c;分辨率越高&#xff0c;对细节的展示越明显。 相机像素…

Linux常用语法

Linux常用语法 0.引言特殊路径符Linux 命令基础格式重要命令mkdir命令echo-tail命令 vi\vim编辑器的三种工作模式vi/vim简单介绍基础命令 运行模式命令模式下的快捷键 进程管理进程的命令 Linux解压缩tar格式zip命令unzip命令 ping,wget,curl等命令的使用Linux端口端口端口的划…

C语言+单片机

今天内容有点水哈哈&#xff08;忙着练焊铁技术了嘻嘻&#xff09; C语言 简单学习了while语言以及其与for语言的区别和适用方法 .循环结构&#xff1a; 初始化语句条件判断句条件控制句 for语句 for(int1;i<100;i){执行条件} for (int i 1; i < 100; i) {printf(&quo…