1

サーバーがクライアントをリッスンし、受信データの大文字を提供するTCP/IPに基づいた基本プロジェクトを作成しています。

Server.java:

import java.io.*;
import java.net.*;
public class Server 
{

    public static void main(String[] args) throws Exception
    {
        ServerSocket ss = new ServerSocket(7948);
        Socket s= ss.accept();
        System.out.print("Server connected\n");

        BufferedInputStream bis = new BufferedInputStream (s.getInputStream());
        BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream());

        while(true)
        {
            int a = bis.available();
            byte b[] = new byte[a];
            bis.read(b);
            String str = new String(b);
            str = str.toUpperCase();
            b = str.getBytes();
            bos.write(b,0,b.length);
            bos.flush();

            if(str.equals("BYE"))
                break;
            else
                continue;
        }
        System.out.print("\nServer Disconnecting");
        String str = "Adios Amigo";
        bos.write(str.getBytes());
        bos.flush();

        bis.close();
        bos.close();
        ss.close();
        s.close();
    }
}

Client.java:

import java.io.*;
import java.net.*;
public class Client 
{

    public static void main(String[] args) throws Exception
    {
        BufferedReader clientStream = new BufferedReader(new InputStreamReader(System.in));
        String str; 
        int a;
        byte[] b;

        Socket s = new Socket(InetAddress.getLocalHost(), 7948);

        BufferedOutputStream bos = new BufferedOutputStream (s.getOutputStream());
        BufferedInputStream bis = new BufferedInputStream (s.getInputStream());

        one:while(true)
        {
            str = clientStream.readLine();
            b =str.getBytes();
            bos.write(b);
            bos.flush();

            a=bis.available();
            b = new byte[a];
            bis.read(b);
            str = new String (b);
            str.trim();
            System.out.print("The server says: "+str);
            if (str.equals("BYE"))
            {
                bis.read(b);
                str = new String (b);
                System.out.print("The server says: "+str);
                break one;
            }
        }

        s.close();
        clientStream.close();
        bos.close();
        bis.close();
    }
}

プログラムは、1つの問題を除いて正常に動作しています。クライアント側での出力は、2つの入力の後に行われます。これは、最初の出力を取得するためにクライアント側から2つの入力を提供する必要があることを意味し、これは継続します。バグを追跡できません。誰か助けてもらえますか?

4

1 に答える 1

3

クライアントでは、データをサーバーに送信し、すぐに呼び出しa.available()ます。この関数は、サーバーからデータが送信されるのを待ちません。が呼び出されるまでにサーバーがデータで応答する可能性は低いため.available()、関数はゼロを返します。

このため、バイト配列b(今後はよりわかりやすい変数名を使用してください) の長さはゼロです。

サイズ 0 の配列が作成されたら、最後に呼び出してデータを待ちますbis.read()- .read() はブロッキング呼び出しです。サーバーからのデータを待ちます。読み込んでいる配列のサイズがゼロであるため、このデータは実際には読み込まれません。これにより、空の文字列が出力されます。

次のコードは問題を解決しますが、将来的には使用をお勧めしません.available()- 私の経験では信頼性が低いです。データの読み取りを試みるだけで、データが利用可能かどうかを確認する必要があります。

クライアント.java:

    one:while(true)
    {
        str = clientStream.readLine();
        b =str.getBytes();
        bos.write(b);
        bos.flush();

        while (bis.available() <= 0)
        {
            // wait for data!
        }

        a=bis.available();
        b = new byte[a];
        bis.read(b);
        str = new String (b);
        str.trim();
        System.out.print("The server says: "+str);
        if (str.equals("BYE"))
        {
            bis.read(b);
            str = new String (b);
            System.out.print("The server says: "+str);
            break one;
        }
    }
于 2013-03-02T07:42:03.100 に答える