2016-07-27 7 views
2

私はDCC SEND部分を追加したばかりの新しいIRCクライアントを作成しました。したがって、両方のユーザーに直接ファイル転送をサポートします。何も、空想、私はGUIのクライアントとDjangoの電源にircのpythonライブラリを使用しています。偉大なminiupnpc libはポートフォワーディングを担当します。ただし、ファイルが正常に送受信されている間は、速度は絶対に誇張です.20 KB /秒に近似します。サーバーをテストするために、私はHexchatを使ってパッケージを送った:アップロード速度は最大の理論的な帯域幅速度(言い換えれば優秀)であった。私は逃したかもしれない何らかのバッファを探してみました。結局のところ、私はアップロードスピードがなぜこんなに泥だらけであるか分からないことは絶対に考えていないと言わざるを得ない。ここに私のアップロードスクリプトの関連部分があります。Python3;データ送信時の速度:IRCプロトコル、DCCファイル転送

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

私たちはあなたが見るパフォーマンスを再現する方法がないので、これについては何も言いません。私の推測です:ファイルを1KBのチャンクで読み込み、そのチャンクを1KBのパケットとして送信すると、明らかにパフォーマンスが低下します。少なくとも、ファイルは64/128/512 KB単位で読み取られ、可能な限りネットワーク上で送信するパケットのサイズを増やしてください。 – Bakuriu

+0

その場合、bytesAcknowledgedがクライアントから送信されたacknoldgementと同じではない理由はありますか?それは単なる 'structured = struct.pack("!Q "、self.dict [bot] [" received_bytes "])'そして 'connection.send_bytes(structured)' – mrj

+0

あなたが私に何を求めているのか分かりません。ソケットを介してデータを送信するとき、*カーネル*がメッセージをより多くのパケットに分割することを決定すると、クライアントのデータ読み込みが少なくなることに注意してください。必要なすべてのデータを受け取るまで、複数の通話を行うのはあなたの責任です。 – Bakuriu

答えて

0

私が既に疑っていたように、バクリュは指摘したように、この問題は確かにfile.read(buffer)行にありました。私は最終的になぜstruct.packエラーがあるのか​​を知りました。バイト確認が送信者に正しく返送されましたが、いくつかのパケットが一緒に結合されることがありました。すなわち、受信されたすべてのパケットについて、8バイトの長さのパックされた符号なし整数の形で応答が応答されます。時にはsock.recv()は入力データを十分に速く読み取っていないので、長さが8のbytesオブジェクトではなく、長さが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つのバイトをお読みください。今それは魅​​力のように働き、アップロード速度は私の帯域幅によって許容される最大の理論上のアップロード速度です!

関連する問題