2013-08-19 27 views
6

SPDY protocolを介していくつかの基本的な要求をスクリプトしたいと思っています。プロトコルは、送信するフレームを、非常に特定の長さとバイトオーダーのバイナリデータで構成されているものとして定義します。バイナリデータをPythonでソケット経由で送信する

私は、ソケット(HTTP)を介して文字列を送信する小さなプログラムしか書いていません。たとえば、SPDYコントロールフレームヘッダーを実装するにはどうすればよいですか?私はbitstringライブラリとnumpyを使用して、コントロールフレームヘッダーのすべての異なるセクションのサイズを制御しようとしましたが、実際には何も動作していません。現在のPythonのSPDYライブラリはcythonとCのデータ型を使用しており、私はそれが非常に予測不可能であることがわかりました。純粋なPythonで単純なリクエストを構築する方法や、プロトコル定義のようなものを構築してソケットに送信する方法については、どうやって簡単にどうやって構築できるのだろうと思いましたか?

答えて

15

通常、bytearrayクラスがあなたの友人になります(あなたの質問が正しく分かっている場合)。ソケット経由で送ることができます:

my_bytes = bytearray() 
my_bytes.append(123) 
my_bytes.append(125) 

// my_bytes is b'{}' now 

s.send(my_bytes) 

バイトに続いてバイトを作成します。また、これは、あなたがデータを受信したときに動作します:

data = s.recv(2048) 
my_bytes = bytearray(data) 

私はSPDYプロトコルについて多くを知らないが、例えば制御ビットはメッセージの最初のビット(ないバイト)です。あなたはバイナリを介してAND例えばmy_bytesからそれを取り出すことができます。

control_frame = my_bytes[0] & 128 

128バイナリので、バイナリで10000000であり、唯一のあなたの最初のビットを与えるためである(各バイトは、我々が持っている理由だ8ビットであることを覚えておいてください7ゼロ)。

これは、手動で行われる方法です。もちろん、私はいくつかのライブラリを使うことをお勧めします。なぜなら、適切なプロトコルハンドラを書くにはかなりの時間がかかります。あなたはそれが非常に難しく、効率的ではないかもしれません。

+0

ありがとう私はこれを探していますが、0bとしてそれぞれを初期化している場合、どのようにバイト文字を読み込み可能な文字列として出力できますか? – ubiQ

+0

@ubiQビット?ビットは0または1です。bytearrayを印刷する場合は、単に 'print my_bytes'を実行してください。 Pythonインタプリタは自動的に各バイトを文字列表現に変換する必要があります。 「読み取り可能」ではない可能性があることに注意してください(正確に意味するものに依存します)。 – freakish

+0

コンソールで文字列として読みたいのですが、生のバイナリを出力していますatm – ubiQ

0

struct moduleを使用して、ヘッダー形式を文字列で定義し、直接解析することもできます。

パケット生成するには:

fmt = 'B I 4b' 
your_binary_data = pack(fmt, header_data) 
sock.sendall(your_binary_data) 

FMTは、ヘッダフォーマットを示します( '私は4bとB' は明らかにあなたのSPDYヘッダー、例のために働いていない、だけです)。残念なことに、おそらく大きなチャンクを解析し、それをあなたのフォーマットに従って分割することによって、バイトアラインされていないヘッダーフィールドを処理する必要があります。

unpacker = struct.Struct('B I 4b') 
unpacked_data = unpacker.unpack(s.recv(unpacker.size)) 

unpacked_dataが解析されたデータとの組を含むであろう:ヘッダを解析する、ことを別に

構造体モジュールは、Python値とPython文字列として表されたC構造体の間の変換を実行します。私はこのアプローチの効率については保証していませんが、fmt文字列を調整するだけで、異なるプロトコルを解析するのに役立ちました。

関連する問題