繁体   English   中英

使用 Socket 的简单聊天应用程序

[英]simple chat application using Socket

我正在尝试创建一个简单的聊天应用程序,希望将消息从一个客户端发送到另一个/或客户端和服务器之间,但是我的消息没有被发送。 我不确定这里的端口(8080)以及我从互联网上复制的。 谁能帮助我我做错了什么? 在此处输入图像描述 Client.java 主要

  {
   con = new Socket("192.168.0.1", 8080);
     while (true) {
        try {
            
            DataInputStream input = new DataInputStream(con.getInputStream());
            String string = input.readUTF();
            textArea.setText(textArea.getText() + "\n" + "Server: " + string);
        } catch (Exception ev) {
             textArea.setText(textArea.getText()+" \n" +"Network issues ");

             try {
                    Thread.sleep(2000);
                    System.exit(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
        }
        
            

    }

}

 private void btnNewButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
    if (textField.getText().equals("")) {
JOptionPane.showMessageDialog(null, "You cannot send an empty message!");
            }else  {
                textArea.setText(textArea.getText() + "\n" + "Client : " + textField.getText());
    try {
                    DataOutputStream output = new DataOutputStream(con.getOutputStream());
                    output.writeUTF(textField.getText());
                } catch (IOException e1) {
                    textArea.setText(textArea.getText() + "\n " + " Network issues");
                    try {
                        Thread.sleep(2000);
                        System.exit(0);
                    } catch (InterruptedException e2) {
                        e2.printStackTrace();
                    }

                }
                textField.setText("");
            }

服务器.Java

private  void serverConnection() throws IOException {
    System.out.println("Test");
    server = new ServerSocket(8080);
    
     con = server.accept();
     lblNewLabel_2.setText("Client found !");
        lblNewLabel_2.setForeground(new Color(0, 0, 128));
     while (true) {
        try {
            
            DataInputStream input = new DataInputStream(con.getInputStream());
            String string = input.readUTF();
            textArea.setText(textArea.getText() + "\n " + "Client: " + string);
                            System.out.println(string);
        } catch (Exception ev) {
             textArea.setText(textArea.getText()+" \n" +"Network issues ");
             
                try {
                    Thread.sleep(2000);
                    System.exit(0);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
        }

    }
}

Swing 不是螺纹,是单螺纹。

这意味着您不应从事件调度线程的上下文之外更新 UI(或 UI 所依赖的某些 state),并且不应从 EDT 的上下文中执行任何长时间运行或阻塞操作。

首先查看Swing 中的并发以了解更多详细信息。

一旦解决方案可能是使用SwingWorker 这允许您在它们自己的线程的上下文中执行长时间运行或阻塞操作,但提供了一种简单的方法来向 UI 发出信号表明更改已安全发生。 有关更多详细信息,请参阅工作线程和 SwingWorker

以下是一个非常基本的示例。 它是自包含的,因此代码可以充当客户端或服务器。 这与localhost相关联,因此您需要在本地运行两个实例。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingWorker;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private ReadMessageWorker readWorker;

        private DataInputStream inputStream;
        private DataOutputStream outputStream;

        private ServerSocket serverSocket;
        private Socket socket;

        private JTextField messageField;
        private JTextArea messageArea;

        private JButton startServerButton;
        private JButton startClientButton;
        private JButton shutDownButton;

        public TestPane() {
            setLayout(new BorderLayout());

            messageField = new JTextField(10);
            messageArea = new JTextArea(10, 20);

            messageField.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        String text = messageField.getText();
                        outputStream.writeUTF(text);
                        appendMessage(text);
                        messageField.setText(null);
                    } catch (IOException ex) {
                        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                        JOptionPane.showMessageDialog(TestPane.this, "Could not send message", "Error", JOptionPane.ERROR_MESSAGE);
                    }
                }
            });

            add(new JScrollPane(messageArea));
            add(messageField, BorderLayout.NORTH);

            startServerButton = new JButton("Start server");
            startClientButton = new JButton("Start client");
            shutDownButton = new JButton("Shutdown");
            shutDownButton.setEnabled(false);

            JPanel actionsPanel = new JPanel();
            actionsPanel.add(startServerButton);
            actionsPanel.add(startClientButton);
            actionsPanel.add(shutDownButton);

            add(actionsPanel, BorderLayout.SOUTH);

            startServerButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            createServer();
                        }
                    }).start();
                }
            });
            startClientButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            createClient();
                        }
                    }).start();
                }
            });
            shutDownButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    shutdown();
                }
            });
        }

        protected void didStartServer() {
            if (!EventQueue.isDispatchThread()) {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        didStartServer();
                    }
                });
                return;
            }

            startServerButton.setEnabled(false);
            startClientButton.setEnabled(false);
            shutDownButton.setEnabled(true);
        }

        protected void didStartClient() {
            if (!EventQueue.isDispatchThread()) {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        didStartClient();
                    }
                });
                return;
            }
            startServerButton.setEnabled(false);
            startClientButton.setEnabled(false);
            shutDownButton.setEnabled(true);
        }

        protected void didShutdown() {
            if (!EventQueue.isDispatchThread()) {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        didShutdown();
                    }
                });
                return;
            }
            startServerButton.setEnabled(true);
            startClientButton.setEnabled(true);
            shutDownButton.setEnabled(false);
        }

        protected void createClient() {
            try {
                didStartClient();
                appendMessage("Connecting to server");
                socket = new Socket("localhost", 8080);
                inputStream = new DataInputStream(socket.getInputStream());
                outputStream = new DataOutputStream(socket.getOutputStream());
                appendMessage("Connected to server\n");
                createMessageWorker();
            } catch (IOException ex) {
                Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(this, "Could not create client socket", "Error", JOptionPane.ERROR_MESSAGE);
            }
        }

        protected void createServer() {
            try {
                didStartServer();
                appendMessage("Starting server");
                serverSocket = new ServerSocket(8080);
                appendMessage("Waiting for client");
                Socket socket = serverSocket.accept();
                appendMessage("Client connected client\n");
                inputStream = new DataInputStream(socket.getInputStream());
                outputStream = new DataOutputStream(socket.getOutputStream());
                createMessageWorker();
            } catch (IOException ex) {
                Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(this, "Could not create server socket", "Error", JOptionPane.ERROR_MESSAGE);
            }
        }

        protected void createMessageWorker() {
            readWorker = new ReadMessageWorker(inputStream, new ReadMessageWorker.MessageListener() {
                @Override
                public void didRecieveMessage(String message) {
                    appendMessage(message);
                }
            });
            readWorker.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    System.out.println(readWorker.getState());
                    if (readWorker.getState() == SwingWorker.StateValue.DONE) {
                        try {
                            readWorker.get();
                        } catch (InterruptedException ex) {
                            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                        } catch (ExecutionException ex) {
                            Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                            JOptionPane.showMessageDialog(TestPane.this, "Stopped reading due to error", "Error", JOptionPane.ERROR_MESSAGE);
                        }
                        shutdown();
                    }
                }
            });
            readWorker.execute();
        }

        protected void appendMessage(String message) {
            if (!EventQueue.isDispatchThread()) {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        appendMessage(message);
                    }
                });
                return;
            }
            messageArea.append(message + "\n");
        }

        protected void shutdown() {
            shutdownServer();
            shutdownSocket();
            appendMessage("\nShutdown completed\n");
            didShutdown();
        }

        protected void shutdownSocket() {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException ex) {
                }
            }
        }

        protected void shutdownServer() {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException ex) {
                }
            }
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException ex) {
                }
            }
            if (serverSocket != null) {
                try {
                    serverSocket.close();
                } catch (IOException ex) {
                }
            }
        }

    }

    public class ReadMessageWorker extends SwingWorker<Void, String> {

        public interface MessageListener {

            public void didRecieveMessage(String message);
        }

        private DataInputStream dataInputStream;
        private AtomicBoolean continueReading;
        private MessageListener listener;

        public ReadMessageWorker(DataInputStream dataInputStream, MessageListener listener) {
            this.dataInputStream = dataInputStream;
            this.listener = listener;
            continueReading = new AtomicBoolean(true);
        }

        @Override
        protected void process(List<String> chunks) {
            for (String message : chunks) {
                listener.didRecieveMessage(message);
            }
        }

        public void stopReading() {
            continueReading.set(false);
            try {
                dataInputStream.close();
            } catch (IOException ex) {
            }
        }

        @Override
        protected Void doInBackground() throws Exception {
            while (continueReading.get()) {
                String text = dataInputStream.readUTF();
                publish(text);
            }

            System.out.println("Read is now down...");

            return null;
        }

    }
}

进一步的增强可能包括设置两个SwingWorker ,一个充当服务器,一个充当客户端。 这将封装createXxx方法的功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM