2

C++ を使用して、バイナリ情報を含むポスト リクエストを送信しています。コードは次のようになります。

int binary[4] = { 1, 2, 3, 4 };

std::stringstream out;
out << "POST /address HTTP/1.1\r\n";
out << "Host: localhost\r\n";
out << "Connection: Keep-Alive\r\n";
out << "Content-Type: application/octet-stream\r\n";
out << "Content-Transfer-Encoding: binary\r\n";
out << "Content-Length: " << 4*sizeof(int) << "\r\n\r\n";    // 4 elements of integer type

そして、ソケットで開かれた接続にデータを送信します。

std::string headers = out.str();

socket.send(headers.c_str(), headers.size());  // Send headers first
socket.send(reinterpret_cast<char*>(&binary[0]), bufferLength*sizeof(int));  // And array of numbers

しかし、http-protocol を介して純粋なバイトを送信するのは間違っていると言われました。そうですか?たとえば、zeroプロトコルで使用されているため、0 ( ) を送信できません。

それが正しい場合 (ポストリクエストを処理して送信したデータを取得できないため)、代わりに何を使用できますか? おそらく、配列を16進またはbase64urlに変換しますか?

ありがとう。

4

3 に答える 3

3

HTTP経由でバイナリを送信するのは問題ありません。

これは、画像ファイルのアップロードで常に発生します

于 2012-04-23T18:30:27.467 に答える
3

しかし、http-protocolを介して純粋なバイトを送信するのは間違っていると言われました。そうですか?

いいえ、もちろんコンテンツタイプにもよりますが、本体は問題ありません。「オクテットストリーム」はこの点で問題ないはずです。そうです、ゼロバイトを含めることができます。

于 2012-04-23T18:35:10.453 に答える
3

それが間違っていると人々が取り組んでいる問題は、エンディアンについてです。もちろん、httpを使用してバイナリデータを転送することもできますが、相手がそれらを受信すると、正しく解釈できる必要があります。あなたのマシンがリトルエンディアンのマシンだとしましょう。整数は、メモリに(32ビットint)として格納されます。

 01 00 00 00 
 02 00 00 00
 03 00 00 00
 04 00 00 00

そして、これらの16バイトを「そのまま」送信し​​ます。ここで、受信側のマシンが、誰がどのように送信されたかを無視してデータを素朴に取得し、そのマシンがビッグエンディアンのマシンであると仮定します。このようなマシンでは、1、2、3、4のインタージャーのメモリレイアウトは次のようになります。

 00 00 00 01
 00 00 00 02
 00 00 00 03
 00 00 00 04

これは、受信側のマシンの場合、最初の整数は0x01000000であり、送信者が望んでいた0x00000001ではないことを意味します。

整数を常にビッグエンディアン整数として送信する必要があると判断した場合、送信者がリトルエンディアンマシンの場合は、送信する前に整数を適切に「再配置」する必要があります。hton*ホストの32/16ビット整数をビッグエンディアンの「ネットバイトオーダー」に「変換」する(ホストからネット)のような関数があります(逆に、ntoh*ネットからホスト) 。

データはスクランブルされていないことに注意してください。つまり、「そのまま」送信されます。変更されるのは、それらをメモリに保存する方法と、読み取るときにそれらを解釈する方法です。データは、必要に応じて非シングルバイトデータのエンディアンを指定する形式に従って送信されるため、通常は問題になりません(たとえば、PNG形式の仕様、セクション2.1、整数のバイト順序を参照してください。PNGはネットバイト順序を使用します。エンディアン)

于 2012-04-23T19:09:59.560 に答える