2

この送受信スクリプトを作成しましたが、ファイルが破損しています。なぜこの問題が発生するのかわかりません!

送信者.py

#!/usr/bin/env python

from socket import *
import sys

s = socket(AF_INET,SOCK_DGRAM)
host =sys.argv[1]
port = 9999
buf =1024
addr = (host,port)

file_name=sys.argv[2]

f=open(file_name,"rb") 
data = f.read(buf)

s.sendto(file_name,addr)
s.sendto(data,addr)
while (data):
    if(s.sendto(data,addr)):
        print "sending ..."
        data = f.read(buf)
s.close()
f.close()

受信機.py

#!/usr/bin/env python

from socket import *
import sys
import select

host="0.0.0.0"
port = 9999
s = socket(AF_INET,SOCK_DGRAM)
s.bind((host,port))

addr = (host,port)
buf=1024

data,addr = s.recvfrom(buf)
print "Received File:",data.strip()
f = open(data.strip(),'wb')

data,addr = s.recvfrom(buf)
try:
    while(data):
        f.write(data)
        s.settimeout(2)
        data,addr = s.recvfrom(buf)
except timeout:
    f.close()
    s.close()
    print "File Downloaded"

そして、これは私が修正した元の受信機です(100%正常に動作します)

#!/usr/bin/env python

from socket import *
import sys
import select

host="0.0.0.0"
port = 9999
s = socket(AF_INET,SOCK_DGRAM)
s.bind((host,port))

addr = (host,port)
buf=1024

f = open("file.pdf",'wb')

data,addr = s.recvfrom(buf)
try:
    while(data):
        f.write(data)
        s.settimeout(2)
        data,addr = s.recvfrom(buf)
except timeout:
    f.close()
    s.close()
    print "File Donwloaded"

お気づきのように、最初はファイルを作成しています。

Exacted: クライアント => ファイルを送信 (name.ext) => サーバー: 保存 (name.ext)

私の出力:pdfの破損したファイルとtxtの空

4

2 に答える 2

4

ここには2つの問題があります。

構文エラー:

を使用していfrom socket import *ます。それ自体はエラーではありませんが、エラーになるとエラーになりますexcept socket.timeout

UDPの使用:

UDPを使用すると、破損は驚くべきことではありません。ここではおそらくUDPを使用したくないので、TCPに切り替える必要があります。

ここでUDPが適切でない理由は次のとおりです。

  • パケットは失われる可能性がありますが、他のパケットは依然として宛先に到達する可能性があります。
  • パケットが重複する可能性があります
  • パケットが間違った順序で到着する可能性があります

SOCK_DGRAMTCPへの切り替えには、コードのリファクタリングが含まれることに注意してください(単に置き換えるよりも少し複雑ですSOCK_STREAM)が、あなたの場合は、それを行う必要があります


UDPが悪いと言っているわけではありませんが、あなたの場合は適切ではありません。

于 2012-12-21T16:28:54.820 に答える
4

あなたのコードの問題:

  • データがソケットを介して送信される場合、通常、下位層は複数の sendTo 呼び出しからのデータをマージし、それらを一緒に送信してネットワーク負荷を軽減します。
  • ファイルの最初の 1024 バイトを 2 回送信しています。

あなたがすべきこと:

実際のファイルのバイナリ表現に存在しないように、いくつかの文字 (「**_$$」など) を含む区切り文字列を使用します。次に、この区切り文字をファイル名の末尾に追加します。

while ループを開始する前に、ファイルから再度読み取ります。

受信側で、すべてを 1 つのストリームに受信してから、区切り記号を使用して分割します。ファイル名とファイル データが表示されます。

アップデート:

作業コード (Ubuntu / Windows XP)

# ----- sender.py ------

#!/usr/bin/env python

from socket import *
import sys

s = socket(AF_INET,SOCK_DGRAM)
host =sys.argv[1]
port = 9999
buf =1024
addr = (host,port)

file_name=sys.argv[2]

s.sendto(file_name,addr)

f=open(file_name,"rb")
data = f.read(buf)
while (data):
    if(s.sendto(data,addr)):
        print "sending ..."
        data = f.read(buf)
s.close()
f.close()

# ----- receiver.py -----

#!/usr/bin/env python

from socket import *
import sys
import select

host="0.0.0.0"
port = 9999
s = socket(AF_INET,SOCK_DGRAM)
s.bind((host,port))

addr = (host,port)
buf=1024

data,addr = s.recvfrom(buf)
print "Received File:",data.strip()
f = open(data.strip(),'wb')

data,addr = s.recvfrom(buf)
try:
    while(data):
        f.write(data)
        s.settimeout(2)
        data,addr = s.recvfrom(buf)
except timeout:
    f.close()
    s.close()
    print "File Downloaded"

使用法

>> python recevier.py

>> python sender.py localhost filename.txt
于 2012-12-21T17:19:34.273 に答える