Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python发送/接收二进制数据_Python_Sockets_Networking - Fatal编程技术网

Python发送/接收二进制数据

Python发送/接收二进制数据,python,sockets,networking,Python,Sockets,Networking,我正在尝试用python(v3)发送和接收二进制数据。我尝试的方法是在客户端手动创建一个字节字符串,然后通过套接字将其发送到服务器。在服务器端,我接收数据并手动访问各个位以解析消息 这是客户端的外观: remoteIP = "164.107.112.72" remotePort = 34562 remoteStruct = remoteIP.split('.', 4) remoteIPBytes = ((int)(remoteStruct[0])).to_bytes(1, byteorder='

我正在尝试用python(v3)发送和接收二进制数据。我尝试的方法是在客户端手动创建一个字节字符串,然后通过套接字将其发送到服务器。在服务器端,我接收数据并手动访问各个位以解析消息

这是客户端的外观:

remoteIP = "164.107.112.72"
remotePort = 34562
remoteStruct = remoteIP.split('.', 4)
remoteIPBytes = ((int)(remoteStruct[0])).to_bytes(1, byteorder='little') + ((int)(remoteStruct[1])).to_bytes(1, byteorder='little') + ((int)(remoteStruct[2])).to_bytes(1, byteorder='little') + ((int)(remoteStruct[3])).to_bytes(1, byteorder='little')

headerStruct = remoteIPBytes + remotePort.to_bytes(2, byteorder='little')
sequenceNum = 0
size = #filesize

data = headerStruct + sequenceNum.to_bytes(1, byteorder='little') + (1).to_bytes(1,byteorder='little') + size.to_bytes(4, byteorder='little')
#data is then sent to server
这是服务器处理数据的方式:

serversock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)   # UDP Datagram
host = '164.107.112.70'
serversock.bind((host, localPort))

seqNum = 0

#get size
size = 0
var = serversock.recvfrom(12)
seqNum = int.from_bytes((str(var))[6], byteorder='little')
在最后一行代码中,我得到一个错误,即(str(var))被视为unicode字符串而不是二进制字符串。然而,如果我不强制转换为字符串,我会得到一个访问越界错误

有人能给我解释一下python中发送和接收二进制数据的正确方法是什么吗?我曾尝试在发送数据之前/之后使用struct.pack和unpack,但在解包过程中总是会出错,即使格式字符串相同

(int)(remoteStruct[0])

这看起来很像一些C代码。Python没有像C这样的类型转换

int
指的是一个对象。使用它的方式是调用它,就像调用函数一样

而是编写类似于
int(remoteStruct[0])
的代码。你写的东西之所以有效,是因为额外的括号是完全多余的,不会改变意思。不过,这不仅仅是句法上的差异。这是两种语言类型系统的基本区别

不过,这与你的问题无关

IPBytes = ((int)(remoteStruct[0])).to_bytes(1, byteorder='little') + ((int)(remoteStruct[1])).to_bytes(1, byteorder='little') + ((int)(remoteStruct[2])).to_bytes(1, byteorder='little') + ((int)(remoteStruct[3])).to_bytes(1, byteorder='little')
这是一种将IPv4地址打包为四个字节的极其冗长的方法。请尝试以下方法:

import socket
print socket.inet_pton(socket.AF_INET, "1.2.3.4")
虽然这也与你的问题没有直接关系

您的
索引器问题的根源(我猜这是您遇到的例外,您说的“访问越界错误”实际上并不存在于Python的内置类型中-不要转述错误,逐字引用它们)很可能在以下位置附近:

var = serversock.recvfrom(12)
注意返回值:返回值是一对(字节,地址)

如果您尝试在
6
处索引到此对象,则肯定会引发
索引器,是的

但是,使用
str
获取此对的unicode字符串表示形式并没有真正的帮助-尽管它可能会防止索引操作失败,因为生成的unicode字符串可能足够长。:)不过,你会收到垃圾

相反,请尝试索引到您读取的字节:

data, addr = serversock.recvfrom(12)

if len(data) > 6:
    seqNum = ord(data[6])
请注意,您确实需要注意此处的长度检查。您将
12
传递给
recvfrom
并不意味着它返回12个字节。这意味着它最多返回12个字节。您不希望您的程序在第一次有人向您发送短数据报时出现未经处理的异常