いくつかのポートでリッスンしている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形式も参照してください。フォーマッターまたはパーサーは、ゼロから簡単に作成できます。