2010-12-28 15 views
10

は私が持っているこのようなバイト配列:C++で配列を分割して結合する方法は?

lzo_bytep out; // my byte array 
size_t uncompressedImageSize = 921600; 

out = (lzo_bytep) malloc((uncompressedImageSize + 
      uncompressedImageSize/16 + 64 + 3)); 
wrkmem = (lzo_voidp) malloc(LZO1X_1_MEM_COMPRESS); 

// Now the byte array has 802270 bytes 
r = lzo1x_1_compress(imageData, uncompressedImageSize, 
     out, &out_len, wrkmem); 

私は65,535バイトの下に小さな部分に分割するにはどうすればよい(バイト配列が、私がしたい一つの大きな画像で上限65,535バイトを持っているUDP経由で送信されます)それらの小さなチャンクを連続アレイに戻します。

答えて

41

この問題は、UDPパケットが到着または発注できない、または破棄されるという問題があります。これにはTCPを使用します。それが何のためだ。

+1

しかし、私はUDPでこれをやりたいと思います。私は一度全体の画像を送信してから、変更されたピクセルだけを送信して、次のパケットが小さくなり、1つのUDPパケットに収まるようにします。 TCPより速く、速度が必要なため、UDPが必要です。 –

+23

@リチャード:TCPより速く動作するこれを正しく行う接続を実装することはできません。初期の大きなチャンクを送信するためにTCP接続を開いてから、更新用にUDPを使用します(更新が失われたり破棄された場合、回復することができます; UDPパケットは失われたり破棄される可能性があります。これは、このような低レイテンシを必要とするゲームサーバーです。つまり、サウンドファイルなどはTCP経由で転送されますが、プレイヤーの位置などはUDP(CounterStrikeサーバー)経由で送信されます。 –

+2

理論上は真です。それほど実践的ではありません。 –

13

アレイを「分割する」必要はありません。あなたはちょうどそれの別の部分を指す必要があります。

通常のUDP write()関数を使用していると仮定すると、いくつかの引数が必要です。それらの1つはバッファへのポインタで、もう1つは長さです。

あなたが最初の65535のバイトを取得したい場合は、あなたのバッファがwrkmemにあり、長さは二65535バイトのために65535

で、あなたのバッファがwrkmem + 65535であり、あなたの長さは65535

です3番目の65535バイト、バッファーはwrkmem + 2 * 65535、長さは65535です。

それを得るには?

(つまり、他のポスターは正しいと思いますが、TCPを使用する必要があります)。

もう一方では、配列を再結合するには、全体に十分なメモリを割り当ててから、memcpy()のようなコピー関数を使って到着するチャンクを正しい位置にコピーする必要があります。 UDPは順番に作品を配信しない可能性があり、すべて配信することはできないことに注意してください。

+1

+1 - もちろん、どちらの側でも、パケットが異常に到着したかどうか、または完全に破棄されたかどうかを検出することはできません。したがって、営業担当者はこれらのタスクを引き渡すための独自の仕組みを実装する必要があります。 –

+13

明るい面を見てください:彼は自分自身のTCP実装を再実装しようとするポインタ算術について多くのことを学びます。 –

+1

これは良い点です...私は彼がこれから撤退している私の当座預金口座ではないことを願っています:) –

1

ØMQのようなメッセージベースのミドルウェアを試し、圧縮されたイメージ全体を1つのメッセージとして送り、ミドルウェアを非同期で実行し、できるだけ速い速度で再配信を管理したい場合があります。 BSDソケット互換のAPIを提供するので、コードを簡単に移行でき、必要に応じてさまざまな基礎となるトランスポートプロトコルを簡単に交換することができます。

他のメッセージシステムも利用できます。

void my_free (void *data, void *hint) 
{ 
    free (data); 
} 

    /* ... */ 

size_t uncompressedImageSize = 921600, compressedImageSize = 0; 
size_t out_len = (uncompressedImageSize + uncompressedImageSize/16 + 64 + 3); 
lzo_bytep out = (lzo_bytep)malloc (out_len); 
lzo_voidp wkrmem = (lzo_voidp)malloc (LZO1X_1_MEM_COMPRESS); 
zmq_msg_t msg; 

rc = lzo1x_1_compress (imageData, uncompressedImageSize, 
         out, &compressedImageSize, wrkmem); 
assert (compressedImageSize > 0); 
rc = zmq_msg_init_data (&msg, out, compressedImageSize, my_free, NULL); 
assert (rc == 0); 
/* Send the message to the socket */ 
rc = zmq_send (socket, &msg, 0); 
assert (rc == 0);