-4

以下は、マルチユーザー チャットを処理するクライアントとサーバーのコードです。しかし、あるクライアントが「終了」と書き込むと、現在接続されている他のクライアントも終了し、別のクライアントに接続できなくなります。誰でもこれを手伝ってもらえますか?

ここに私のクライアントコードがあります:

class TCPClientsc {
    public static void main(String argv[]) throws Exception {
        String modifiedSentence;
        InetAddress inetAddress = InetAddress.getLocalHost();
        System.out.println(inetAddress);

        Socket clientSocket = new Socket(inetAddress, 6789);
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        CThread write = new CThread(inFromServer, outToServer, 0, clientSocket);
        CThread read = new CThread(inFromServer, outToServer, 1, clientSocket);
    }
}

class CThread extends Thread {
    BufferedReader inFromServer;
    DataOutputStream outToServer;
    Socket clientSocket = null;
    int RW_Flag;
    public CThread(BufferedReader in, DataOutputStream out, int rwFlag, Socket clSocket) {
        inFromServer = in;
        outToServer = out;
        RW_Flag = rwFlag;
        clientSocket = clSocket;
        start();
    }
    public void run() {
        String sentence;
        try {
            while (true) {
                if (RW_Flag == 0) {// write
                    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
                    sentence = inFromUser.readLine();

                    // System.out.println("Writing ");
                    outToServer.writeBytes(sentence + '\n');
                    if (sentence.equals("quit"))
                        break;

                } else if (RW_Flag == 1) {
                    sentence = inFromServer.readLine();
                    if (sentence.endsWith("quit"))
                        break;
                    System.out.println("(received)" + sentence);
                }
            }
        } catch (Exception e) {
        } finally {
            try {
                inFromServer.close();
                outToServer.close();
                clientSocket.close();

            } catch (IOException ex) {
                Logger.getLogger(CThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

サーバーコード:

class TCPServersc {
    static int i = 0;
    static SThread tt[] = new SThread[100];
    static SThread anot[] = new SThread[100];
    public static void main(String argv[]) throws Exception {
        String client;
        String capitalizedSentence;
        ServerSocket welcomeSocket = new ServerSocket(6789);

        while (true) {
            Socket connectionSocket = welcomeSocket.accept();
            i++;
            System.out.println("connection :" + i);
            BufferedReader inFromClient = new BufferedReader(newInputStreamReader(connectionSocket.getInputStream()));
            DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
            BufferedReader inFromMe = new BufferedReader(new InputStreamReader(System.in));

            tt[i] = new SThread(inFromClient, outToClient, tt, 0, connectionSocket, i);
            anot[i] = new SThread(inFromMe, outToClient, tt, 1, connectionSocket, i);
        }
    }
}

// ===========================================================
class SThread extends Thread {
    BufferedReader inFromClient;
    DataOutputStream outToClient;
    String clientSentence;
    SThread t[];
    String client;
    int status;
    Socket connectionSocket;
    int number;

    public SThread(BufferedReader in, DataOutputStream out, SThread[] t, int status, Socket cn, int number) {
        inFromClient = in;
        outToClient = out;
        this.t = t;
        this.status = status;
        connectionSocket = cn;
        this.number = number;
        start();
    }

    public void run() {
        try {
            if (status == 0) {
                clientSentence = inFromClient.readLine();
                StringTokenizer sentence = new StringTokenizer(clientSentence, " ");

                // ///////////////////////////////////////////////////////////
                if (sentence.nextToken().equals("login")) {
                    String user = sentence.nextToken();
                    String pass = sentence.nextToken();
                    FileReader fr = new FileReader("file.txt");
                    BufferedReader br = new BufferedReader(fr);
                    int flag = 0;
                    while ((client = br.readLine()) != null) {
                        if ((user.equals(client.substring(0, 5))) && (pass.equals(client.substring(6, 10)))) {
                            flag = 1;
                            System.out.println(user + " has logged on");
                            for (int j = 1; j <= 20; j++) {
                                if (t[j] != null)
                                    t[j].outToClient.writeBytes(user + " has logged on" + '\n');// '\n' is necessary
                            }
                            break;
                        }
                    }
                    if (flag == 1) {
                        while (true) {
                            clientSentence = inFromClient.readLine();
                            System.out.println(user + " : " + clientSentence);
                            for (int j = 1; j <= 20; j++) {
                                if (t[j] != null)
                                    // '\n' is necessary
                                    t[j].outToClient.writeBytes(user + " : " + clientSentence + '\n');
                            }
                            // if(clientSentence.equals("quit"))break;
                        }
                    }
                }
            }
            // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            if (status == 1) {
                while (true) {
                    clientSentence = inFromClient.readLine();
                    if (clientSentence.equals("quit"))
                        break;

                    System.out.println("Server: " + clientSentence);
                    for (int j = 1; j <= 20; j++) {
                        if (t[j] != null)
                            t[j].outToClient.writeBytes("Server :" + clientSentence + '\n');// '\n' is necessary
                    }
                }
            }
        } catch (Exception e) {
        } finally {
            try {
                // System.out.println(this.t);
                inFromClient.close();
                outToClient.close();
                connectionSocket.close();
            } catch (IOException ex) {
                Logger.getLogger(SThread.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}
4

1 に答える 1

1

このコードには多くの問題があります。

  • まず、将来的には、適切にフォーマットされた、より小さく簡潔なコード フラグメントを投稿してください。基本的に、投稿のすべてを再フォーマットする必要がありました。
  • あなたがキャッチしているが、例外を除いて何もしていない場所がいくつか見られます。これは非常に悪い習慣です。少なくとも、キャッチした例外を印刷/ログに記録する必要があります。これがあなたの問題に貢献していると思います。
  • RW_Flag私は非常に紛らわしいと思います。その場合、2 つのクライアント スレッドが必要です。1 つはサーバーへの書き込みSystem.in用で、もう 1 つは読み取り用です。2 つのことを行う 1 つのクライアント スレッドを持たないでください。statusサーバーのフラグと同じです。それは2つの異なるスレッドである必要があります。
  • int flag = 0;サーバーの代わりに、それはboolean loggedIn;. C スタイルのフラグの代わりに Java でブール値を使用し、より適切な変数名を使用します。コードの可読性はそれだけで報われます。statusRW_flagなどについても同じです。
  • 巨大なコード ブロックの代わりに、連続するコードをメソッドに移動する必要があります: handleSystemIn()handleClient()talkToServer(). コードにさらにメソッドを作成し、個々のコード ブロックを縮小すると、読みやすく、デバッグしやすく、理解しやすくなります。
  • synchronized (tt)その配列の使用ごとにブロックが必要です。ttメインスレッドが追加された場合にすべて使用している複数のスレッドができたらaccept、更新を同期する必要があります。

スパゲッティ コードは解析が難しすぎますが、すぐには問題がわかりません。どこかで例外をスローしていると思われます。これが、最初のクライアントが終了した後にクライアントが接続できない理由です。それ以外は、引き続きSystem.out.printlnデバッグを自由に使用して、どのメッセージがどこに送信されているかを確認します。

于 2012-05-17T12:55:09.753 に答える