web-dev-qa-db-ja.com

Python-sock.recvを文字列に変換する

pythonとネットワーキングを使って調べています。

while True:
   data = sock.recv(10240)

これは間違いなく聞いています。ただし、テキスト文字列に変換する必要があるようです。

struct.unpack()を使用している人を見たことがありますが、それがどのように機能するか正確にはわかりません。変換する方法は何ですか?

11
coffeemonitor

recv から返されるのはbytes文字列です。

ソケットからデータを受信します。戻り値は、受信したデータを表すbytesオブジェクトです。

Python 3.xで bytes 文字列をUnicodeテキスト str 文字列に変換するには、文字列がどの文字セットでエンコードされているかを知る必要がありますなので、 decode を呼び出すことができます。たとえば、UTF-8の場合:

_stringdata = data.decode('utf-8')
_

(Python 2.xでは、bytesstrと同じであるため、文字列は既にgotです。ただし、 Unicodeテキストunicode文字列を取得したい場合は、3.xと同じです。)

人々がよく struct を使用する理由は、データが8ビットまたはUnicodeテキストだけではなく、他の形式であることです。たとえば、各メッセージを「 netstring ":長さ(ASCII桁の文字列として)、その後に_:_セパレータ、次にlengthバイトとして送信することができます。 UTF-8の場合、_,_などの_b"3:Abc,"_。 (形式にはバリエーションがありますが、これはバーンスタイン標準ネットストリングです。)

人々がnetstringsまたは他の同様のテクニックを使用する理由は、TCPを使用しているときにメッセージを区切るための何らかの方法が必要だからです。各recvは、反対側がsendで渡したものの半分を提供するか、3つのsendsと4番目の一部を提供します。そのため、recvデータのバッファーを蓄積し、そこからメッセージをプルする必要があります。そして、1つのメッセージが終了し、次のメッセージがいつ開始するかを通知する方法が必要です。改行なしでプレーンテキストメッセージを送信するだけの場合は、改行を区切り文字として使用できます。それ以外の場合は、ネットストリング、区切り文字として_\0_を使用する、区切り文字として改行を使用するが、データ内の実際の改行をエスケープする、または次のような自己区切られた構造化フォーマットを使用するJSON。

23
abarnert

Python 2.7.xおよびそれ以前では、dataはすでに文字列です。Python 3.x、dataはバイトオブジェクト。バイトを文字列に変換するには、decode()メソッドを使用します。decode()には、 'utf-8'などのコーデック引数が必要です。

4
Joshua D. Boyd