0

TCP を介して相互に通信する C サーバーと Java クライアントを実装しました。問題は、クライアントが文字列を送信するときに、C サーバーの recv() 呼び出しが文字を読み取ってすぐに戻ることです。recv() にブレークポイントを設定してからステップオーバーを実行すると、サーバーは送信された文字列全体を受信します。Cで使用しているrecv呼び出しは次のとおりです

char tempBuffer[256] = {'\0'};  
int retVal = recv(hClientSocket, tempBuffer, sizeof(tempBuffer), 0);

これが Java クライアントです。

clientSocket = new Socket("127.0.0.1", 24886);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
outToServer.writeBytes("alert(\"hi\")");

私の質問は、各文字を個別に受信するために C サーバー コードに while ループを配置することなく、これを機能させる方法はありますか? これを行う最善の方法は何ですか?ここに記載されている C++ クライアントを実装しましたが、正常に動作します。したがって、Java+C++ の相互運用性に何らかの問題があると推測しています。ありがとう!

4

4 に答える 4

4

Scott M の言うことは Java 側 ( の使用についてflush) には当てはまりますが、通信プロトコル全体を作り直す必要があります。

文字列入力が終了したことを認識するために、Cコードに送信されると予想されるバイト数を伝えるか(これが最も追跡しやすいでしょう)、何らかの種類の終了文字を使用する必要があります(たとえば、nullターミネータバイト)。

ネットワーク層がトランジションを恣意的に切断しないという保証は絶対にありません。そのため、防御的にコードをrecv作成し、内部で使用するために組み立てる必要がある部分的なデータを常に受信することを期待してください。

于 2012-04-13T12:45:09.167 に答える
2

Javaストリームをフラッシュしてみてください。これらは通常バッファリングされているため、ストリームへのバイトの書き込みに多少の遅延が発生します。コードをフルスピードで台無しにするのに十分な長さ、デバッグ中に文字列全体を送信するのに十分な長さ。

于 2012-04-13T12:37:19.997 に答える
2

TCP では、「while ループを配置する」ことを回避する方法はありませんrecv()。TCP は、サイズが制限されたパケット サービス (IP) の上に構築されたストリーム プロトコルです。TCP は独自の「パケット化」を行い、実際には非常にスマートです。これは、ソケットからの次の読み取りで返されるバイト数がわからないことを意味します。

機能するよく知られた戦略は、アプリケーションレベルのプロトコルを設計して、メッセージ自体がその大きさを示し、処理するメッセージが完全になるまでループで読み取ることです。

そうは言っても、期待する量を知っていると仮定して、特定の量のデータを待機するために使用できるkludge、つまり呼び出しMSG_WAITALLのフラグがあります。recv(2)

于 2012-04-13T12:45:09.067 に答える
1

私はかつて、文字列の長さを示すヘッダーを持つことで試しました..そのようにdinはメッセージの終わりをチェックしなければなりません..

于 2012-04-13T12:42:24.920 に答える