1

この問題を約5時間理解しようとしてきましたが、データを送信するためのすべての手順が完了しましたが、サーバーからクライアントへのメッセージは受信できませんが、サーバーにメッセージを受信することはできません。コマンド ラインでチャット クライアント プログラムを作成/学習する初期段階にいます。サーバーコードは次のとおりです。

CServer クラス:

public class CServer {

private static int port=2008, maxConnections=0;
private static String shutDownServer = "no";

public static void main(String[] args) throws IOException{


    ServerSocket listen = new ServerSocket(port);
    Socket server;

    while(shutDownServer.equalsIgnoreCase("no")){

        doComm connection;

        System.out.println("\nWaiting for clients to connect...");

        server = listen.accept(); // accept incomming connections from client
        System.out.println("Client connected. Location: " + server.getInetAddress().getHostName());
        connection = new doComm(server);

        Thread thread = new Thread(connection);
        thread.start();
    }



}

public void shutDownServer(String command){

    this.shutDownServer = command;
}
}

次に、スレッド内の各クライアントを処理する doComm クラス:

public class doComm implements Runnable{

Socket server;
private String clientData;

  public doComm(Socket server){

      this.server = server;
  } 

  public void run(){

     try {

      BufferedReader fromClient = new BufferedReader(new InputStreamReader(server.getInputStream()));
      DataOutputStream toClient = new DataOutputStream(server.getOutputStream());

      clientData = fromClient.readLine();
         System.out.println("Client sent: "+clientData);

(( 問題 -imo- は、このステートメントのいずれかである可能性があります: ))

      toClient.writeBytes("Recieved your sentence '"+clientData+"' and more to come :)!");

    //server.close();

  } catch (IOException e) {
    System.out.println("IOException on socket listen: " + e);
    e.printStackTrace();
  }

  }
}

次に、クライアント クラス CClient:

    public class CClient {

    static String address = "localhost";

static int port = 4444;
static Socket echoSocket;

     public CClient(int port, String addr){

         changePort(port);
         changeAddr(addr);
     }

     public static void main(String[] args) throws IOException, UnknownHostException{

         Scanner scan = new Scanner(System.in);

         System.out.println("Please enter the port to connect to: ");
         int temp_port = Integer.parseInt(scan.nextLine());
         System.out.println("Please enter the address of server: ");
         System.out.flush();
         String temp_addr = scan.nextLine();

         CClient client = new CClient(temp_port,temp_addr);

            PrintWriter out = null;
            BufferedReader in = null;

         try{
             System.out.flush();
             echoSocket =  new Socket(address,port);
             out = new PrintWriter(echoSocket.getOutputStream(), true);
             in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
         }
         catch(IOException e){

             System.err.println("IOException error: " + e.getStackTrace());
         }

         BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
    String userInput;

    while ((userInput = stdIn.readLine()) != null) {

        out.println(userInput);
            System.out.println("thingy prints right after this...");

(( またはここ: ))

System.out.println("echo: " + in.readLine());
}
 }

 public void changePort(int port){

     this.port=port;
 }

 public void changeAddr(String addr){

     this.address=addr;
 }
}
4

1 に答える 1

3
  clientData = fromClient.readLine();

  toClient.writeBytes("Recieved your sentence '"+clientData+"' and more to come :)!");

これは非常に一般的な問題であり、その根本的な原因は、通信に使用されているプロトコルの文書化指定の失敗です。ここでは、回線を受信して​​いますが、バイトを送信しています。プロトコルドキュメントがある場合は、行が交換されるか、任意のバイト単位が交換されることを指定します。これは、これらのコード行の1つが間違っていることを示しており、修正することができます。しかし、プロトコルの仕様がなければ、どちら側が間違っているかさえわかりません。

何年にもわたる苦痛なレッスンから私のアドバイスを受けてください-実装する前にプロトコルを文書化してください。次に、それが機能しない場合は、次の3つのステップのプロセスに従うことができます。

  1. クライアントは文書化されたプロトコルに従っていますか?そうでなければ、それは壊れています。

  2. サーバーは文書化されたプロトコルに従っていますか?そうでなければ、それは壊れています。

  3. プロトコル仕様が壊れています。

この場合、プロトコル仕様は、プロトコルの「メッセージ」を構成するものを文書化します。その場合、完全なメッセージを送信し、受信時にこれらのメッセージ境界を見つけるのは、それぞれの側の責任です。ただし、あなたの場合、1つのコードは、行末記号がメッセージ境界をマークすることを期待し、反対側はそれを送信しません。

送信者がメッセージ境界を省略するのは間違っていますか?受信者が受信を主張するのは間違っていますか?何をするのが正しいかを言う仕様がないので、誰も知りません。

于 2013-02-05T19:37:20.990 に答える