套接字的Python C#数据类型



我正在创建一个套接字服务器,以便通过TCP连接并与C#程序通信。目前,我正在尝试创建一种方法,将通过TCP套接字发送的十六进制转换为特定变量(变量类型将在数据包标头中,是的,我确实知道TCP在技术上不是发送数据包的流,但我正在这样设计它(。目前,我已经通过下面的代码将所有的C#整数类型正确地转换为字节码/整数(所有不同的类型都是相同的,只需进行几次编辑即可适应C#类型(

## SBYTE Type Class definition
## C#/Unity "sbyte" can be from -128 to 127
##
## Usage:
##
## Constructor
## variable = sbyte(integer)
## variable = sbyte(bytearray)
## 
## Variables
## sbyte.integer (Returns integer representation)
## sbyte.bytes (Returns bytearray representation)
class sbyte:
def __init__(self, input):
if type(input) == type(int()):
self.integer = input
self.bytes = self.__toBytes(input)
elif type(input) == type(bytearray()):
self.bytes = input
self.integer = self.__toInt(input)
else:
raise TypeError(f"sbyte constructor can take integer or bytearray type not {type(input)}")

## Return Integer from Bytes Array
def __toInt(self, byteArray):
## Check that there is only 1 byte
if len(byteArray) != 1:
raise OverflowError(f"sbyte.__toInt length can only be 1 byte not {len(byteArray)} bytes")
## Return signed integer
return int.from_bytes(byteArray, byteorder='little', signed=True)

## Return Bytes Array from Integer
def __toBytes(self, integer):
## Check that the passed integer is not larger than 128 and is not smaller than -128
if integer > 127 or integer < -128:
raise ValueError(f"sbyte.__toBytes can only take an integer less than or equal to 127, and greater than or equal to -128, not "{integer}"")
## Convert the passed integer to Bytes
return integer.to_bytes(1, byteorder='little', signed=True)

这适用于我目前实现的所有类型,但我想知道是否有更好的方法来处理它?例如使用ctype或其他一些python库。由于这将是一个可能有许多连接的套接字服务器,因此尽可能快地处理这一问题是最好的。或者,如果你看到我还有什么可以改进的,我很想知道。

如果只需要字节数组中的一个整数值,只需对字节数组进行索引:

>>> b = bytearray.fromhex('1E')
>>> b[0]
30

用以下代码测试from_bytes、struct.unpack和numpy.frombuffer之间的差异后:

setup1 = """
byteArray = bytearray.fromhex('1E')
"""
setup2 = """
import struct
byteArray = bytearray.fromhex('1E')
"""
setup3 = """
import numpy as np
type = np.dtype(np.byte)
byteArray = bytearray.fromhex('1E')
"""
stmt1 = "int.from_bytes(byteArray, byteorder='little', signed=True)"
stmt2 = "struct.unpack('b', byteArray)"
stmt3 = "np.frombuffer(byteArray, type)"
print(f"First statement execution time = {timeit.timeit(stmt=stmt1, setup=setup1, number=10**8)}")
print(f"Second statement execution time = {timeit.timeit(stmt=stmt2, setup=setup2, number=10**8)}")
print(f"Third statement execution time = {timeit.timeit(stmt=stmt3, setup=setup3, number=10**8)}")

结果:

First statement execution time = 14.456886599999999
Second statement execution time = 6.671141799999999
Third statement execution time = 21.8327342

从最初的结果来看,struct似乎是实现这一目标的最快方法。除非还有其他图书馆我不见了。

编辑:

根据AKX的建议,我为签名字节添加了以下测试:

stmt4 = """
if byteArray[0] <=127:
byteArray[0]
else:
byteArray[0]-127
"""

并得到以下执行时间:

Fourth statement execution time = 4.581732600000002

走这条路是最快的,尽管稍微超过了使用structs。我必须对每种类型进行测试,以获得最快的字节转换方式,反之亦然,但这个问题现在给了我4种不同的方法来测试每种类型。谢谢

最新更新