3

シンプルな C サーバーと Java クライアントがあります。サーバーからクライアントにテキストファイルを1行ずつ送信しています:

    do {
        send(sockfd, line, strlen(line), 0);
        printf("%s\n", line);
    } while ((fgets(line, 100, fp)) != NULL);  

Javaクライアントで次のように読み取ります。

    Client.getCl().getInputStream().read(inmsg);
    do{             
         decoded = new String(inmsg, "UTF-8");
         System.out.println(decoded);
    }while(Client.getCl().getInputStream().read(inmsg) > 0);  

私の問題は、サーバーからクライアントに「読み取り終了」を送信する方法がわからないことです。クライアントは最後の読み取りでフリーズします。methodeは、受信read()バイト数を含む整数を返し、読み取るものが何もない場合は -1 を返し、バッファーの長さがゼロの場合は 0 を返すことを知っています。クライアントに -1 を返す唯一の解決策は、サーバー側でソケットを閉じることでしたが、それは使用できません。また、次のことを試しました:
1)送信メソッドの最後に長さ0を送信して、長さがゼロであることをクライアントに伝えます:

send(sockfd, NULL, NULL, 0);  

2) フラグを定義して送信:

#define MSG_FIN 0x200
#define MSG_EOR 0x0080

そして再び両方のフラグで:

 send(sockfd, NULL, NULL, MSG_FIN);
 send(sockfd, NULL, NULL, MSG_EOR);  

誰でも私がここで間違っていることを助けてください? ありがとう

4

2 に答える 2

5

同じ TCP ソケットを介して断続的なデータを送信する場合は、送信するデータ内で送信する情報の境界をエンコードする必要があります。この例は、長さプレフィックスを付けてデータの「パケット」を送信することです。これにより、パケットの受信者は、長さプレフィックスが指定するのと同じ数のバイトをソケットから読み取ることができます。

于 2013-12-18T19:33:40.763 に答える
0

リーダーには 2 つの問題があります。常に完全なバッファーを読み取ると仮定します。一度に 1 バイトしか読み取らない限り、これを想定することはできません。また、常にマルチバイト文字全体を読み取ると仮定しますが、マルチバイト文字をまったく使用しない限り、これは当てはまりません。

テキストを書いているので、メッセージの間に新しい行を送信し、ストリームをテキストとして読むことをお勧めします。

BufferedReader br = new BufferedReader(new InputStreamReader(
                        Client.getCl().getInputStream(), "UTF-8"));
for(String line; (line = br.readLine()) != null; ) {
    // process a whole line of text at once. e.g.
    System.out.println(line);
}

これにより、テキストがデコードされ、行全体が読み取られ、マルチバイト文字が処理されます。

于 2013-12-18T20:24:33.760 に答える