2

数日前、スレッドを使用してソケットについて学ぶための実験として、クライアントまたはクライアントサーバーを作成しようとしましたが、誰かが私にswingWorkerを使用する必要があると言いました。使用方法を調査し、実際に実装しましたが、まだ機能しません。接続を取得して .excute() を使用しても、swingWorker スレッドが実行されているようには見えません。皆さんが私が間違っているところを見つけるのを手伝ってくれるなら、それは素晴らしいことです. SwingWorker クラスは startSever() および startClient() メソッドにあります。

    private void startServer() {
        SwingWorker <Void, String> runningServer = new SwingWorker<Void, String>(){
        protected Void doInBackground() {
            try {
                listeningSocket = new ServerSocket(port);
                System.out.println("waiting for connection");
                connection = listeningSocket.accept();
                connected = true;
                System.out.println("Connected");
                String incomeMessage =null;
                while(connected){
                inStream = connection.getInputStream();
                    inDataStream = new DataInputStream(inStream);
                    if (myMessage !=null){
                        outStream = connection.getOutputStream();
                        outDataStream = new DataOutputStream(outStream);
                    outDataStream.writeUTF(myMessage);
                    }

                    if((incomeMessage = inDataStream.readUTF())!=null){
                        clientMessage = incomeMessage;
                        publish(clientMessage);
                        incomeMessage =null;
                    }
                }
            } catch (IOException e) {
                clientMessage = "Connection Lost";
            }
        return null;
    }           
runningServer.execute();
}
4

3 に答える 3

6

これは非常に基本的な例です。

基本的に、プログラムは非同期通信を必要とする (つまり、ソケットからの読み取りとソケットへの書き込みを同時に行う必要がある) ため、各ストリームを個別のスレッドにオフロードする必要があります。

この例の管理プロセスは、まあ、存在しません。現実的には、出力スレッドと入力スレッドをきれいに閉じることができるある種の「接続」マネージャーが必要です。たとえば、ユーザーが「さようなら」と入力したときに、出力スレッドが接続マネージャーにそれを伝えることができるようにする必要があります。接続を終了する必要があります。次に、入力スレッドに新しいメッセージの読み取りを停止して終了するように指示します...

クライアント

public class Client {

    public static void main(String[] args) {

        try {
            Socket master = new Socket("localhost", 8900);
            new Thread(new InputHandler(master)).start();
            new Thread(new OuputHandler(master)).start();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    public static class InputHandler implements Runnable {

        private Socket socket;

        public InputHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            boolean commune = true;
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                while (commune) {
                    String text = reader.readLine();
                    System.out.println("\n<server> " + text);
                    if (text.toLowerCase().equals("bye")) {
                        commune = false;
                    }
                }
            } catch (Exception exp) {
                exp.printStackTrace();
            } finally {
                try {
                    reader.close();
                } catch (Exception e) {
                }
                try {
                    socket.close();
                } catch (Exception e) {
                }
            }
        }
    }

    public static class OuputHandler implements Runnable {

        private Socket socket;

        public OuputHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            boolean commune = true;
            BufferedWriter writer = null;
            try {
                writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                Scanner scanner = new Scanner(System.in);
                while (commune) {
                    System.out.print("> ");
                    String text = scanner.nextLine();
                    writer.write(text);
                    writer.newLine();
                    writer.flush();
                    if (text.equalsIgnoreCase("bye")) {
                        commune = false;
                    }
                }
            } catch (Exception exp) {
                exp.printStackTrace();
            } finally {
                try {
                    writer.close();
                } catch (Exception e) {
                }
                try {
                    socket.close();
                } catch (Exception e) {
                }
            }
        }
    }
}

サーバ

public class Server {

    public static void main(String[] args) {

        try {
            ServerSocket master = new ServerSocket(8900);
            Socket socket = master.accept();
            new Thread(new InputHandler(socket)).start();
            new Thread(new OuputHandler(socket)).start();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    public static class InputHandler implements Runnable {

        private Socket socket;

        public InputHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            boolean commune = true;
            BufferedReader reader = null;
            try {
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                while (commune) {
                    String text = reader.readLine();
                    System.out.println("\n<client> " + text);
                    if (text.toLowerCase().equals("bye")) {
                        commune = false;
                    }
                }
            } catch (Exception exp) {
                exp.printStackTrace();
            } finally {
                try {
                    reader.close();
                } catch (Exception e) {
                }
                try {
                    socket.close();
                } catch (Exception e) {
                }
            }
        }
    }
    public static class OuputHandler implements Runnable {

        private Socket socket;

        public OuputHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            boolean commune = true;
            BufferedWriter writer = null;
            try {
                writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                Scanner scanner = new Scanner(System.in);
                while (commune) {
                    System.out.print("> ");
                    String text = scanner.next();
                    writer.write(text);
                    writer.newLine();
                    writer.flush();
                    if (text.equalsIgnoreCase("bye")) {
                        commune = false;
                    }
                }
            } catch (Exception exp) {
                exp.printStackTrace();
            } finally {
                try {
                    writer.close();
                } catch (Exception e) {
                }
                try {
                    socket.close();
                } catch (Exception e) {
                }
            }
        }
    }
}

アップデート(泣き言)

あなたのソースコードを目の前に置いていますが...

する必要があることは非常に、非常に、めったにないはずですtextMessage.addKeyListener(this)

を使用しているため、代わりにJTextFielda を使用する必要がありますActionListener。これには多くの重要な理由がありますが、主な理由は、「受け入れ」アクションがルック アンド フィールに依存しているという事実です。ほとんどのシステムはEnter「受け入れる」アクションを使用しますが、保証ではありません。

詳細については、アクション リスナーの作成方法を参照してください。

あなたがやろうとしていることの一般的な複雑さを考えると、全体的に良い試みのために+1!

于 2013-01-31T02:47:46.300 に答える
5

このを使用すると、次の変更は単一のtelnetクライアントで機能します。

private PrintWriter out;
...
public void keyPressed(KeyEvent e) {
    if (e.getKeyChar() == KeyEvent.VK_ENTER) {
        myMessage = friendLabel + textMessage.getText();
    if (out != null) {
        out.println(myMessage);
    }
    ...
}
...
protected Void doInBackground() {
    try {
        listeningSocket = new ServerSocket(port);
        System.out.println("Waiting for connection");
        connection = listeningSocket.accept();
        connected = true;
        System.out.println("Connected");
        Scanner in = new Scanner(connection.getInputStream());
        out = new PrintWriter(connection.getOutputStream(), true);
        publish("Connected");
        while (true) {
            publish(in.nextLine());
        }
    } catch (IOException e) {
        clientMessage = "Connection Lost";
        try {
            connection.close();
            System.out.println("Closed");
        } catch (IOException e1) {
            e1.printStackTrace();
            connected = false;
        }
    }
    return null;
}
于 2013-01-31T02:49:00.877 に答える
-1

サーバー ポートは 8900 で、クライアント ポートも 8900 です。サーバーとクライアントが同じマシンで実行されているかどうかが問題かどうかはわかりません...

于 2013-01-31T02:36:53.353 に答える