Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
642 views
in Technique[技术] by (71.8m points)

concurrency - Java socket swingWorker running but no message received or transmitted

A few days ago i tried to create a server - client or client Server as an experiment to learn about socket using a thread but then someone told me that i should use swingWorker. I did some research how to use and have implemented it in as practice but it still doesn't work. the swingWorker thread doesn't look like it is running even tho i get a connection and have used .excute(). If you guys can help spot where i am doing wrong that will be great. SwingWorker class is in the startSever() and startClient() method.

    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();
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's a VERY basic example.

Basically, because you program requires asynchronous communications (that is, you need to be able to read from the socket AND write to it at the same time), you need to offload each stream to a separate thread.

The management process of this example is, well, no existent. Realistically, you should have some kind of "connection" manager that would be able to cleanly close the output and input threads so that, for example, when the user types "bye", the output thread would be able to tell the connection manager that the connection should be terminated. It would then tell the input thread to stop reading any new message and terminate...

Client

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("
<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) {
                }
            }
        }
    }
}

Server

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("
<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) {
                }
            }
        }
    }
}

Update (whine)

While I have your source code in front of me...

There should very, very, rarely be a need to do textMessage.addKeyListener(this)

Because you are using a JTextField, you should be using a ActionListener instead. There are a a number of important reasons for this, but for you, the main one would be the fact that a "accept" action is Look and Feel dependent. While most systems do use Enter as there "accept" action, is not a guarantee.

Have a look at How to Write a Action Listener for more information

Given the general complexity of what you are trying to do, +1 for a overall good attempt!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...