1

これはかなり単純な問題だと思いますが、まだ理解できません。

ネットワーク経由でストリームを送信する機能があります。当然、これは const void * を引数として取ります:

void network_send(const void* data, long data_length)

ソケット経由で送信する前に、特定のヘッダーを char* の形式でこれに付加しようとしています:

  long sent_size = strlen(header)+data_length;
  data_to_send = malloc(sent_size);
  memcpy(data_to_send,header,strlen(header)); /*first copy the header*/
  memcpy((char*)data_to_send+strlen(header),data,dat_length); /*now copy the actual data*/

データが実際に char* である限り、これは正常に機能します。しかし、それが他のデータ型に変更されると、これは機能しなくなります。

受信時に、データを処理する前にデータからヘッダーを削除する必要があります。だから、これがそれを行う方法です:

void network_data_received(const void* data, long data_length)
{
 ........
 memmove(data_from_network,(char*)data_from_network + strlen(header),data_length); /*move the data to the beginning of the array*/
 ProcessFurther(data_from_network ,data_length - strlen(header)) /*data_length - strlen(header) causes the function ProcessFurther to read only certain part of the array*/
}

データが char 型の場合、これも問題なく機能します。ただし、タイプが異なる場合はクラッシュします。

これを適切に実装する方法を誰かが提案できますか?

よろしく、カーン

4

6 に答える 6

2

このコードで何かが私を驚かせます。あなたのヘッダーは実際に文字列ですか?それが構造体である場合は、strlen を sizeof に置き換える必要があります。ゼロで終了していない文字列で strlen を呼び出すと、クラッシュが発生する可能性があります。

2 番目に驚いたことは、受信したデータを読み取るときに、ヘッダーをどこかにコピーする必要があることです。それを使用していない場合、わざわざネットワーク経由で送信する必要はありません。

編集: OK、ヘッダーは http のようなヘッダー文字列です。そこから問題が発生することはありません。テストするだけであれば、実際に分析する必要はありません。

そして、実際に必要な場所にデータを移動する必要があります。バッファの先頭に移動することは、正しいことのようには見えません。

問題がアラインメントに起因する場合は、データを実際のターゲット型の変数にバイト レベルでコピーしてから使用すると、問題は解消されます。

別の解決策があります。バッファを malloc で割り当て、必要なデータ構造を最初に置きます。その後、キャストできるはずです。malloc によって返されるアドレスは、どの型とも互換性があります。

また、C++ を使用している場合、自明でないクラスへのキャストは機能しない可能性があることに注意してください (1 つの理由として、vtable が間違ったアドレスを取得する可能性が高く、他の問題もあります)。

もう 1 つの考えられる問題の原因は、data_length の取得方法です。バイト数である必要があります。それはアイテムの数ではありませんか?確かに、呼び出しコードのヒントが必要です。

于 2010-12-07T12:28:08.777 に答える
2

アライメントが問題になる可能性がありますが、これを実行しているプラ​​ットフォームを指定していません (異なる CPU アーキテクチャには異なるアライメント要件があります)。

後続のデータのアラインメントに対してヘッダーの長さが「間違っている」場合、アクセス違反が発生する可能性があります。

于 2010-12-07T12:24:18.477 に答える
0

data_length呼び出し元のコードで正しく計算されていない可能性があります。それ以外の場合、このコードは @unwind で言及されている可能性のあるアラインメントの問題を除けば問題ないようです。

どのようにheader宣言されますか?可変長はありますか?? の後に終了NUL文字がありheaderませんか?

于 2010-12-07T12:30:05.403 に答える
0

memcpyソースとターゲットが重複している場合 (この例のように) の動作は未定義です。使用する必要があります。memmove()

何がそうでないときに正確に何が起こっているのchar*ですか?void*これらの関数は通常、実際に作業を行う前にキャストします...

于 2010-12-07T12:22:48.030 に答える
0

また、送信者と受信者の両方が同じバイト順序アーキテクチャ (リトル エンディアンとビッグ エンディアン) を使用していることも確認します。

于 2010-12-07T18:40:56.990 に答える
0

を使用しunsigned char * て問題を解決しました。コメントありがとうございます。

于 2010-12-09T04:14:30.043 に答える