0

ここでは、struct.pack の使用法が適切であることがわかりました。コピー/貼り付けエラーのために、間違った変数を使用していました。独自のコードでこのような間違いに注意することを忘れないでください!

見たい場合は、元の質問を以下に示します。


UDP パケットのペイロードとして 2 つの異なる情報を送信する必要があります。これらのパケットは、オブジェクトの宛先に関する情報 (つまり、宛先 IP アドレスと宛先ポート番号) を運びます。正しい情報をパッケージングしていることを他の方法で確認済みです。私の問題は、送信した情報を解読することです。私がエンコードした情報と、それらをエンコードするために使用した方法は次のとおりです。

IP アドレス: xxx.xxx.xxx.xxx (xxx は 0 ~ 255 の任意の数字)

  1. IP アドレスは 4 つの数字のリストに分割されます。

  2. 4 つの数値のリストは、各バイトがリスト番号の 1 つである struct.struct('4B') を使用してパックされます。

  3. 受信側では、これが受信され、同一の struct.struct("4B") を使用してアンパックされます

  4. IP アドレスを表す文字列は、4 つのアンパックされた値と適切に配置されたピリオドを使用して再構築されます。

ポート番号の場合:

ポート番号: 通常は数千単位の単一の整数 (例: 8000、私のテスト値)

  1. struct.struct("H") を使用して格納されます (これは数値を保持する 2 バイトのオブジェクトです)

  2. 受信側で同一の struct.struct("H") を使用してアンパック

エンコードして送信する前に値をチェックしているので、エンコード部分まで正しく処理していると思います。値は正しいです。反対側でそれらを取得してデコードすると、値がすべて間違っており、その理由がわかりません。次に例を示します。

入力 IP とポート:

IP: 164.107.112.70 ポート: 8000

出力 IP とポート:

IP: 64.31.0.0 ポート: 10

これらの問題に遭遇するために、ここで何が間違っているのでしょうか?

編集:要求されたコードは次のとおりです。

#pack IP for transport

#split into four 1-byte values
SplitIP = IP.split('.')

#create a 4-byte struct to pack IP, and pack it in remoteIP
GB = struct.Struct("4B")

remoteIP = GB.pack(int(SplitIP[0]),int(SplitIP[1]),int(SplitIP[2]),int(SplitIP[3]))
#remoteIP is now a 4-byte string of packed IP values


#pack Port for transport

#create a 2-byte struct to pack port, and pack it in remotePort
GBC = struct.Struct("H")

remoteIP = GBC.pack(int(PORT))  #needs another byte
#remoteIP is now a 2-byte string of packed IP values


#Join the two parts together

remoteIP += str(remotePort)

この後、いくつかの追加要素がパックされます (1 バイトのフラグ、ABP の 1 バイトの 0/1 値 (まだ実装されていません)、およびペイロード (この場合、4 バイトの値としてのファイルのサイズ))。 . 次に、ソケット送信コマンドを介して、クライアントが提供するポート番号 (私のテストでは 4000 が使用されます) で同じマシン上の別のプロセスに送信されます。

#get size of file from os command
filesize = bytearray(4)
#save as 4-byte string
filesize = str(os.stat(localfile).st_size)

#add flag
flag1 = bytearray(1)
flag1 = str(1)

#add zerone
if(zerone == 0):
    zerone = 1
else:
    zerone = 0

zeon = str(zerone)

#package the filesize string

filesizestr = ''.join(remoteIP)
filesizestr = filesizestr + flag1 + zeon    #now contains 4,2,1,1 byte arrays

filesizestr += filesize                     #now we have complete packet

s.sendto(filesizestr, ('127.0.0.1', int(TPORT)))

編集: コピー/貼り付けで間違いがありました。これは、コーディングのあらゆる段階で考慮しなければならない、本当に共通の敵です。

現在発生している問題は、IP アドレスは正常に送信されるようになりましたが、ポートが間違っていることです。

送信ポートは 8000 でした

受信したポートは @\x1f でした

その出力を解釈する方法が完全にはわかりません。誰かが何が起こっているのかを理解するのを手伝ってくれるなら、本当に感謝しています。私の推測では、エンコード エラーが発生したか、間違ったデータを取得したかのいずれかです。データに関しては、送信される文字列の配置は次のようになります。

IP は 4 バイト、ポートは 2 バイトなど。

そのため、次の 2 行でその情報を取得します。

packedIP = data[0:4]    #grab 4-byte IP data
packedPort = data[4:6]  #grab 2-byte port data

これでいいですよね?Python の文字列アクセサがどのように機能するのか、まだ少し混乱しています。でもIPは当たったので大丈夫だと思います。

編集:以前の問題を気にしないでください。間違った変数を使用して、もっとばかげたエラーを犯しました。

4

1 に答える 1

1

したがって、理論的には、ワイヤ上のバイトは次のようになります。

A4 6B 70 46 1F 40

しかし、あなたがデコードしたものは

40 1F 00 00 00 0A

最初のセットの最後の 2 バイトが、2 番目のセットの最初の 2 バイト (反転) であることが疑われます。使用しているコードを確認できますか? これは、正確な問題の特定に役立つ場合があります。

また、マシンはリトルエンディアンですか、それともビッグエンディアンですか? バイトパック構造体を作成するときは、通常、ネットワーク順序 (ビッグ エンディアン) を使用します。つまり、構造体文字列の前に感嘆符を付ける必要があります ( http://docs.python.org/2/library/struct.htmlを参照)。

編集:あなたの問題はこの行です:

remoteIP = GBC.pack(int(PORT))  #needs another byte

そのはず

remotePort = GBC.pack(int(PORT))  #needs another byte
于 2013-11-12T20:34:57.287 に答える