6

いくつかのポートでリッスンしているc#で記述された単純なサーバーがあります。C ++のアプリケーションがあり、サーバーに情報を送信するためのアプリケーションが必要です。この情報は、5つの整数を含む構造体です。「ID=3、anotherInt=5...」のような文字列としても送信できると思っていました。それは良い考えですか?そうでない場合は、どうすればよいですか?

それを機能させる方法は?あなたのアドバイスは何ですか?

ありがとうございました。

4

4 に答える 4

3

クライアント コードの send() メソッドを修正する必要があります。sizeof() は、文字列の長さを見つける方法が間違っています。「ln」に適用されたキャストは、必要なものにはまったく適していません。<<このリンク>> の例をチェックして、どのように機能するかを確認してください。ところで、サーバーの C# コードが予想通りに動作するためには、深刻な書き直しが必要です。4096 バイトのバッファを使用しており、Read() の呼び出しは、送信全体を一度にフェッチすることが保証されていません。必要なものをすべて読み取っていることを確認するには、Read のためだけのループが必要です。もちろん、これには通信セマンティクスの明確な定義が必要です。楽しいネットワーキング!

于 2013-01-06T18:12:54.047 に答える
3

コードに誤りがあると思います。

char *ln = "String to send";
connect(client_socket, (struct sockaddr *)&clientService, sizeof(clientService));  
send(client_socket,(const char*)&ln, sizeof(ln), 0);

send 関数のプロトタイプは次のとおりです。

ssize_t send(int socket, const void *message, size_t length, int flags);

ln はすでに char バッファーへのポインターです。ポインターのアドレスである &ln を渡しています。「イン」だけじゃないの?

于 2013-01-06T18:04:34.363 に答える
2

まず、(const char*)&ln正しくありません。lnは であるchar *ため、 を使用してそのアドレスを&取得すると、 が取得されchar **、それが にキャストされますchar *。これは未定義の動作です。&オペレーターを取り除きたいと思うでしょう。また、おそらくポインターとは何か、およびそれらの使用方法について読みたいと思うでしょう。

経験則として、コンパイラをシャットダウンさせるために willy-nilly をキャストしないでください。エラーはあなたに何かを伝えようとしています。ただし、これsockaddrsockaddr_in正しいです。APIはそのように設計されています。コンパイラ オプションでオンに-Wallすると、正しい場所で警告が表示されます。

また:あなたはしたいのですがstrlen(ln)、そうではありませんsizeof

ポインターのクイック アンド ダーティ ランダウン

型が*変数名の前に含まれている場合、変数はその型の値へのポインターを保持します。ポインターは C# の参照によく似ており、データの場所を保持するです。これらは通常、関数が呼び出し元が所有するデータの一部を参照する必要がある場合に、関数に渡されます。文字列は、文字列の最初の文字へのポインタであるとして表されます。ポインターに関連する 2 つの演算子はとです。左辺値を取り、その値へのポインタを返します。ポインタを取り、それが指す値を返します。この場合、 として文字列があり、呼び出している関数はchar *&*&*char *char **であるため、キャストしたり or を使用したりせずに直接渡すことができます&。ただし、他の関数では a がstruct sockaddr_inあり、それが必要なstruct sockaddr *ので、(正しく) を使用&して a を取得しstruct sockaddr_in *、それを a にキャストしstruct sockaddr *ます。これは「型パニング」と呼ばれ、API の不快な現実です。Google は、タイプのしゃれについて、私よりも詳しく説明してくれるでしょう。

于 2013-01-06T18:05:54.910 に答える
0
connect(client_socket, (struct sockaddr *)&clientService, sizeof(clientService));

これは問題ありませんが、この行は次のようになります。

send(client_socket,(const char*)ln, strlen(ln), 0);

ここで、変換(const char*)は省略できます。あなたのコードでは、ポインター ln の値が (正しく) 送信されますが、ほとんどの場合、それが指している文字列全体を送信する必要があります。

送信するメッセージに関して: 整数を ascii に変換することは悪い考えではありません。JSON またはGoogle の protobuf形式も参照してください。フォーマッターまたはパーサーは、ゼロから簡単に作成できます。

于 2013-01-06T18:11:45.947 に答える