いくつかのポートでリッスンしているc#で記述された単純なサーバーがあります。C ++のアプリケーションがあり、サーバーに情報を送信するためのアプリケーションが必要です。この情報は、5つの整数を含む構造体です。「ID=3、anotherInt=5...」のような文字列としても送信できると思っていました。それは良い考えですか?そうでない場合は、どうすればよいですか?
それを機能させる方法は?あなたのアドバイスは何ですか?
ありがとうございました。
クライアント コードの send() メソッドを修正する必要があります。sizeof() は、文字列の長さを見つける方法が間違っています。「ln」に適用されたキャストは、必要なものにはまったく適していません。<<このリンク>> の例をチェックして、どのように機能するかを確認してください。ところで、サーバーの C# コードが予想通りに動作するためには、深刻な書き直しが必要です。4096 バイトのバッファを使用しており、Read() の呼び出しは、送信全体を一度にフェッチすることが保証されていません。必要なものをすべて読み取っていることを確認するには、Read のためだけのループが必要です。もちろん、これには通信セマンティクスの明確な定義が必要です。楽しいネットワーキング!
コードに誤りがあると思います。
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 を渡しています。「イン」だけじゃないの?
まず、(const char*)&ln
正しくありません。ln
は であるchar *
ため、 を使用してそのアドレスを&
取得すると、 が取得されchar **
、それが にキャストされますchar *
。これは未定義の動作です。&
オペレーターを取り除きたいと思うでしょう。また、おそらくポインターとは何か、およびそれらの使用方法について読みたいと思うでしょう。
経験則として、コンパイラをシャットダウンさせるために willy-nilly をキャストしないでください。エラーはあなたに何かを伝えようとしています。ただし、これsockaddr
はsockaddr_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 は、タイプのしゃれについて、私よりも詳しく説明してくれるでしょう。
connect(client_socket, (struct sockaddr *)&clientService, sizeof(clientService));
これは問題ありませんが、この行は次のようになります。
send(client_socket,(const char*)ln, strlen(ln), 0);
ここで、変換(const char*)
は省略できます。あなたのコードでは、ポインター ln の値が (正しく) 送信されますが、ほとんどの場合、それが指している文字列全体を送信する必要があります。
送信するメッセージに関して: 整数を ascii に変換することは悪い考えではありません。JSON またはGoogle の protobuf形式も参照してください。フォーマッターまたはパーサーは、ゼロから簡単に作成できます。