ここでは、struct.pack の使用法が適切であることがわかりました。コピー/貼り付けエラーのために、間違った変数を使用していました。独自のコードでこのような間違いに注意することを忘れないでください!
見たい場合は、元の質問を以下に示します。
UDP パケットのペイロードとして 2 つの異なる情報を送信する必要があります。これらのパケットは、オブジェクトの宛先に関する情報 (つまり、宛先 IP アドレスと宛先ポート番号) を運びます。正しい情報をパッケージングしていることを他の方法で確認済みです。私の問題は、送信した情報を解読することです。私がエンコードした情報と、それらをエンコードするために使用した方法は次のとおりです。
IP アドレス: xxx.xxx.xxx.xxx (xxx は 0 ~ 255 の任意の数字)
IP アドレスは 4 つの数字のリストに分割されます。
4 つの数値のリストは、各バイトがリスト番号の 1 つである struct.struct('4B') を使用してパックされます。
受信側では、これが受信され、同一の struct.struct("4B") を使用してアンパックされます
IP アドレスを表す文字列は、4 つのアンパックされた値と適切に配置されたピリオドを使用して再構築されます。
ポート番号の場合:
ポート番号: 通常は数千単位の単一の整数 (例: 8000、私のテスト値)
struct.struct("H") を使用して格納されます (これは数値を保持する 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は当たったので大丈夫だと思います。
編集:以前の問題を気にしないでください。間違った変数を使用して、もっとばかげたエラーを犯しました。