0

重複の可能性:
アプリケーションがifステートメントを入力しないのはなぜですか

Javaでコンソールクライアントサーバーアプリケーションを作成しようとしています。ソケットを使用して、私は現在、単純なログインシステムと単純なコマンドシステムを持っています。ログインシステムが機能しているようで、接続が機能しているようです。

ただし、コマンドシステムはまったく機能していないようです。サーバーがコマンドを受信すると、何も返送されていないように見えます。

だから私の主な質問は、コマンドが受信されたときにサーバーがクライアントに何も返送しないのはなぜですか?

これが私のサーバーです:

import java.io.*;
import java.net.*;

class TCPServer2
{
public static void main(String argv[]) throws Exception
{
//error is caused by command being used differently to login & username/password strings.
//consider removing command as a set string and adding a statement which takes
//the readLine value, adds it to a string and the command is the value of said string.
//If string is = "listLanguages" do this else if = "getcost" do this else "invalid cmd".

    ServerSocket welcomeSocket = new ServerSocket(6789);
Map<String, String> userDetails = new HashMap<String, String>();
userDetails.put("JOHN","UNCP");
userDetails.put("MATT","UNCP");
    String Command;
    String username;
    String username1;
    String password;
    String password1;
    String cmd;
    while(true)
    {
        Socket connectionSocket = welcomeSocket.accept();
        BufferedReader inFromClient =
           new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
        DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
        username = inFromClient.readLine();
        System.out.println("\nUsername received: " + username);
        password = inFromClient.readLine();
        System.out.println("\nPassword received: " + password);
        username1=username.toUpperCase();
        password1=password.toUpperCase();


if (userDetails.get(username1).equals(password1))
{
    outToClient.writeBytes("Hello " + username1);
              outToClient.writeBytes("\nOther users registered on the server currently include: \n");

  for (String str : userDetails.keySet())
  {
      outToClient.writeBytes(str);
  }

}
else
{
   outToClient.writeBytes("Invalid Username and/or password.\n");
}

                        BufferedReader inFromClient2 =
           new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
        DataOutputStream outToClient2 = new DataOutputStream(connectionSocket.getOutputStream());
        Command = inFromClient2.readLine();
        System.out.println("\nCommand received: " + Command);


if(Command.equals("listTranslations"))
{
outToClient2.writeBytes("English,Thai,Geordie,etc.");
}
else
{
if(Command.equals("getCost"))
{
outToClient2.writeBytes("£100\n");
}
else
{
outToClient2.writeBytes("Invalid Command");
}
}

} 

    }
}

これが私のクライアントです:

import java.io.*;
import java.net.*;

class TCPClient2
{
public static void main(String argv[]) throws Exception
{
     String userName;
     String passWord;
     String loginInfo;
     String loginInfo2;
     String loginInfo3;
     String command;
     String commandInfo;
     String commandInfo2;

     BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
     Socket clientSocket = new Socket("localhost", 6789);
     DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
     BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

     System.out.println("Username: ");
     userName = inFromUser.readLine();
     outToServer.writeBytes(userName + "\n");

     System.out.println("Password: ");
     passWord = inFromUser.readLine();
     outToServer.writeBytes(passWord + "\n");

     loginInfo = inFromServer.readLine();
     System.out.println(loginInfo);
     loginInfo2 = inFromServer.readLine();
     System.out.println(loginInfo2);
     loginInfo3 = inFromServer.readLine();
     System.out.println(loginInfo3);

     System.out.println("Please enter a command: ");
     command = inFromUser.readLine();
     outToServer.writeBytes(command);

     commandInfo = inFromServer.readLine();
     System.out.println(commandInfo);
     commandInfo2 = inFromServer.readLine();
     System.out.println(commandInfo);



     clientSocket.close();
 }
}

クライアントはサーバーに接続します。クライアントはユーザーにログインを要求します。ユーザーはログイン情報を入力します。サーバーはログイン情報を確認します。サーバーはクライアントに正常にログインしたことを通知します。クライアントはユーザーに要求します。コマンドを入力するには、ユーザーはコマンドを入力します(価格を要求するため)。コマンドはサーバーに送信されます。サーバーは目的の情報を送り返します。その後、コマンドの入力を求められているユーザーにループバックする必要があります。

ただし、これは行いません。ユーザーがログインした後、「サーバーに登録されている他のユーザーは現在含まれています:」行で、データを出力せずにスタックします。

なぜこれをしているのですか?

4

3 に答える 3

1

スタックしている理由は、おそらくクライアントとサーバーの両方がreadLine()上にあり、デッドロックが発生しているためです。クライアントは着信データを待機し、サーバーも待機します。これはコマンドpromtクライアントおよびサーバーであり、データを送信するための「ボタン」がないためです。

現在印刷されている変数を示す情報を追加して、スタックした場所を簡単に追跡できるようにします。例:

loginInfo = inFromServer.readLine();
     System.out.println("loginInfo client Side "+loginInfo);

これにより、クライアントにあるloginInfo変数を出力していることがわかります。これで、フローを簡単にたどり、問題が発生している場所を特定できます。

コマンドpromtserver/ client(guiのみ)を実行したことはありませんが、現在のデザインでユーザーのリストを印刷する場合は、すべてのユーザー名で文字列を作成し、文字列全体をクライアントに送信することをお勧めします、次にクライアントはStringBuilderで文字列を分離し、結果を出力します。これは、クライアントがサーバーが送信する「ユーザー名」の数を知らないためです。

于 2012-05-09T15:04:58.380 に答える
0

次の行を送信する前に、データ出力ストリーム ライターのバッファをフラッシュしてみましたか。また、1 つのクライアントに対して 2 つの異なるデータ出力ストリーム ライターと入力ストリーム リーダーを使用する理由にも興味があります。プログラムの両方の部分に同じものを使用できませんでしたか。

于 2012-05-09T15:01:55.717 に答える
0

問題は、不適切なソケット データの読み取り/書き込み方法にあります。ソケットにデータを書き込むときは、常に flush() する必要があります。ラインにコメントすると

 //loginInfo3 = inFromServer.readLine();
 //System.out.println(loginInfo3);

次に、クライアントに「コマンドを入力してください」と表示されますが、コマンドを入力した後、ソケットがフラッシュ/クローズされないため、サーバーは待機し続けます。

サーバーとクライアントのコードの主な問題は、適切なハンドシェイクです。ブロックにコードを書き、ソケットを開き、コマンドを書き、応答を取得し、ソケットを閉じる必要があります。これは、データを入力する一般的な方法です。ソケットをクラブし、適切なフラッシュ/クローズなしでデータをストリームに書き込んでいるため、さまざまな時点で待機しています。

于 2012-05-09T15:19:44.297 に答える