0

python-2.7を使用してIPv6 および UDP ソケットを使用しています。私は特に、すべてのリンクローカル アドレス デバイス ( を含む) が中央のサーバー エンティティからのクエリに応答するIPv6 マルチキャストに焦点を当てています。 ff02::1fe80::

.ihexこれらのデバイスには、 ( Intel Hex )形式のプログラムを必要とするマイクロコントローラーが接続されています。ファイルのスニペットは次のとおりです。

:103100005542200135D0085A8245381131400031EE
:103110003F4002000F9308249242381120012F8370
:103120009F4F1E390011F8233F4036000F930724AC

andstructのような関数を使用して使用する方法を考えていますが、数Kbsのサイズのこのようなihexファイルを送信しても目的が解決するかどうかはわかりません。packunpack

次のようなことができますか:

#!/usr/bin/env python

from struct import pack, unpack
import socket
.   # Create a UDP socket and Bind it..
.
myHexCode = open("Filename.ihex")
dataToSend = struct.pack('Paramaters for packing', myHexCode)
.
. Send data to socket..

パッキング パラメータはどうなりますか? (!ビッグまたはスモール エンディアン>、または<16 進ファイルを使用する必要がありますか?)

ノート

  • これらのプロトコルはどちらscpTCPで動作し、マルチキャストをサポートしていないため、使用できません。また、ネットワークの損失が高くなる可能性がある環境 (ワイヤレス メディア)で作業しています。sftp

  • また、このクエリから提案されているようにIntel Hexファイルをバイナリに変換してから、バイナリをパックする必要がありますか?

4

1 に答える 1

1

マルチキャストで UDP を使用してファイルを複数のコンシューマーに送信することは、ファイル全体が 1 つのパケットに収まらない限り、問題が発生するようです。UDP パケットはさまざまな理由でドロップ/破棄される可能性があり、ネットワークは損失が多いと既に述べています。各コンシューマがドロップされたパケットを追跡して送信者に通知する方法が必要です。

そうは言っても、それは確かに実行可能です。アイデアの 1 つ: 数回マルチキャストする最初のパケットを作成します。おそらくその間にランダムな遅延があります (すべてのステーションが確実に受信できるようにするため)。この最初のパケットは、「新しいプログラムを送信しようとしています-N個の後続のレコードパケットを期待してください」のように効果的です)。

次に、おそらくそれぞれ 2 回、N 個のパケットを送信します。各データ パケットに識別用のシリアル番号を入れ、消費者に受信したものを追跡させます。ある程度の遅延の後 (またはすべてが受信されたとき)、各コンシューマに、「N 個のパケットをすべて取得しました」または「レコード 5、98、144、および 3019 を取得できませんでした」(または任意のスキーム) という状態パケットで応答させます。損失性に基づいて適切です)。

次に、送信者はこれらの失われたレコード ID を収集し、すべてのコンシューマーがファイル全体を受信したことに満足するまでそれらを再送信できます。

それらをデータグラムに詰め込むために、「intel hex」またはバイナリのどちらを送信するかは問題ではないと思います。どちらの場合も、バイト ストリームとして送信する必要があります。バイナリはサイズが小さくなるため、必要なパケットが少なくなりますが、送信プロセスに他の違いはありません。同じ理由で、選択したバイト順は違いはありません。struct単純なバイト ストリームの場合、パックするために を使用する必要はまったくありません。送信するだけです。

bytes注: python3 はとタイプを区別するため、strpython3 でこれを維持するには、ファイルを「バイナリ」モードで開く必要があります。

ただし、上記のように、各パケットでシリアル番号を送信することになる場合、そのシリアル番号は何らかの方法でフォーマットする必要があります。数値を ascii 文字列としてフォーマットできますが、nostruct.packは必要ありません。または、バイナリでフォーマットする場合は、パッキング形式を選択する必要があります。従来、ネットワーク パケットは「ネットワーク バイト オーダー」(実際にはビッグ エンディアンと同じ) を使用しますが、これは慣例に過ぎません。

もし私がそうしていたら、次のように各レコードを構成するかもしれません:

  • レコード タイプ (バイナリ、1 バイト -- これがデータ パケットであることを示す)
  • レコード ID (バイナリ、2 バイト -- シリアル番号 [またはファイルの大きさに応じてそれ以上])
  • レコード データ長 (バイナリ、レコード データ フィールドの長さを示す 2 バイト)
  • レコードデータ (バイナリ、N バイト)

次に、次のようなものでペイロードを作成できます。

payload = struct.pack("!BHH", record_type, record_id, len(record_data))
          + record_data

ここではstruct.pack、「ヘッダー」フィールド (ネットワーク バイト オーダーを使用してパック) を含む 5 バイトの文字列を作成し、既にバイト文字列である record_data を追加するだけです。

于 2016-03-31T16:18:18.077 に答える