Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.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 蟒蛇3;发送数据时的速度:IRC协议、DCC文件传输_Python_Performance_File Transfer_Irc - Fatal编程技术网

Python 蟒蛇3;发送数据时的速度:IRC协议、DCC文件传输

Python 蟒蛇3;发送数据时的速度:IRC协议、DCC文件传输,python,performance,file-transfer,irc,Python,Performance,File Transfer,Irc,我已经编写了一个新的IRC客户端,我刚刚添加了DCC发送部分,因此支持应用程序两个用户的直接文件传输。没什么,想象一下,我正在使用irc python库为GUI的客户端和Django提供支持。伟大的miniupnpc库负责端口转发。然而,当文件被正确地发送/接收时,速度绝对可怕:大约为20kb/s。为了测试服务器,我使用Hexchat发送了一个包:上传速度是最大的理论带宽速度(换句话说,非常好)。我试着找一个我可能错过的缓冲区。最后,我必须说,我完全不知道为什么我的上传速度如此糟糕,需要一些洞察

我已经编写了一个新的IRC客户端,我刚刚添加了DCC发送部分,因此支持应用程序两个用户的直接文件传输。没什么,想象一下,我正在使用irc python库为GUI的客户端和Django提供支持。伟大的miniupnpc库负责端口转发。然而,当文件被正确地发送/接收时,速度绝对可怕:大约为20kb/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()
def on_dcc_connect(self、c、e):
t=threading.Timer(0,上传\u监控,[self,c])
t、 开始()
日志(“与%s”%self.nickname.write()建立的连接)
self.file=open(self.filename,'rb')
self.sendBlock()
def发送块(自):
如果self.position>0:
self.file.seek(self.position)
block=self.file.read(1024)
如果是块:
self.dcc.send_字节(块)
self.bytesSent=self.bytesSent+len(块)
其他:
#没有更多要发送的内容,传输完成。
self.connection.quit()
_dccsend上的def(自身、c、e):
如果e.arguments[1].split(“,1)[0]=“RESUME”:
self.position=int(e.arguments[1]。拆分(“”[3])
c、 ctcp(“DCC”,自我昵称,“接受%s%d%d”%(
os.path.basename(self.filename),
self.eport,
自我定位)
_dccmsg上的def(自身、连接、事件):
数据=事件。参数[0]
bytesAcknowledged=struct.unpack(“!Q”,data)[0]
如果BytesAcknowedself.bytesSent:
self.connection.quit()
返回
self.sendBlock()

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

正如我已经怀疑的那样,正如巴库留所指出的那样,问题确实存在于
文件.read(buffer)
行。我终于发现了为什么我有
struct.pack
错误:字节确认被正确地发送回发送方,但有时几个数据包被连接在一起。也就是说,对于接收到的每个数据包,以8字节长度的压缩无符号整数的形式向发送方应答确认。有时,
sock.recv()
读取传入数据的速度不够快,因此,我没有使用长度为8的字节对象,而是使用长度为16、24、32、40或更多的字节对象。这就是为什么我不能用
struct.pack(“!Q”,data)
解包。一旦我明白了这一点,就很容易找到解决方案:

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

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

我们真的不能对此说什么,因为我们无法重现您看到的性能。我的猜测是:以1KB的数据块读取文件,并将所述数据块作为1KB的数据包发送,显然会导致非常低的性能。至少可以以64/128/512 KB的数据块读取该文件,并尝试尽可能增加您在网络上发送的数据包的大小。在这种情况下,您是否知道为什么BytesAcknowed与客户端发送的Acknowledge不同?它只是
structured=struct.pack(“!Q”,self.dict[bot][“received_bytes”])
然后
连接。发送(structured)
我不明白你在问我什么。注意,当通过套接字发送数据时,内核可能决定将消息分成更多的数据包,这将导致客户端读取更少的数据。您有责任执行多个调用,直到收到所需的所有数据。我的意思是,当我增加文件缓冲区时,我突然读取的dccmsg比我应该读取的要大。这是否意味着我有一个套接字缓冲区,它在刷新之前首先编译数据?