Python3;发送数据时的速度:IRC协议,DCC文件传输

时间:2016-07-27 14:39:15

标签: python performance file-transfer irc

我已经编写了一个新的IRC客户端,我刚刚添加了DCC SEND部分,因此支持应用程序用户的直接文件传输。没什么,很奇怪,我正在使用irc python库为客户端和Django提供GUI。伟大的miniupnpc lib负责端口转发。但是,在正确发送/接收文件的同时,速度绝对是可怕的:大约20 KB / s。为了测试服务器,我使用Hexchat发送了一个包:上传速度是最大理论带宽速度(换句话说,优秀)。我试着找一些我可能错过的缓冲区。最后,我必须说我完全不知道为什么我的上传速度如此糟糕,需要一些洞察力。这是我上传脚本的相关部分。

def on_dcc_connect(self, c, e):
    t = threading.Timer(0, upload_monitoring, [self, c])
    t.start()    
    log("connection made with %s" % self.nickname).write()
    self.file = open(self.filename, 'rb')
    self.sendBlock()


def sendBlock(self):
    if self.position > 0:
        self.file.seek(self.position)
    block = self.file.read(1024)
    if block:
        self.dcc.send_bytes(block)
        self.bytesSent = self.bytesSent + len(block)
    else:
        # Nothing more to send, transfer complete.
        self.connection.quit()

def on_dccsend(self, c, e):
    if e.arguments[1].split(" ", 1)[0] == "RESUME":
        self.position = int(e.arguments[1].split(" ")[3])
        c.ctcp("DCC", self.nickname, "ACCEPT %s %d %d" % (
        os.path.basename(self.filename),
        self.eport,
        self.position))



def on_dccmsg(self, connection, event):
    data = event.arguments[0]
    bytesAcknowledged = struct.unpack("!Q", data)[0]
    if bytesAcknowledged < self.bytesSent:
        return
    elif bytesAcknowledged > self.bytesSent:
        self.connection.quit()
        return
    self.sendBlock()

send_bytes(block)方法是基本的socket.send()方法。当我增加file.read()的缓冲区时,我得到struct.pack错误,因为我的发送脚本没有正确读取客户端的块接收确认(也是struct.pack):数据不是字节长度8.是不是file.read缓冲区必须更改?如果是这样,为什么收到的字节确认在发件人方面与下载方不一样?如果没有,我应该在哪里提高上传速度?

1 个答案:

答案 0 :(得分:0)

正如我已经怀疑的那样,正如Bakuriu指出的那样,问题确实存在于file.read(buffer)行。我终于找到了为什么我有struct.pack错误:字节确认已正确发送回发件人,但有时一些数据包连接在一起。也就是说,对于接收到的每个分组,以8字节长度打包的无符号整数的形式向发送方应答确认。有时,sock.recv()没有足够快地读取传入数据,然后,我有一个长度为16,24,32,40或更长的字节对象,而不是长度为8的字节对象。这就是为什么我不能用struct.pack("!Q", data)打开包装的原因。一旦我弄明白,解决方案很容易找到:

def on_dccmsg(self, connection, event):
    data = event.arguments[0][-8:]
    bytesAcknowledged = struct.unpack("!Q", data)[0]

我刚从sock.recv()读取的数据中读取最后8个字节,而不是读取所有内容。现在它就像一个魅力,上传速度是我的带宽允许的最大理论上传速度!!!