【问题标题】:Sockets and ServerSockets Server/Client GUI Chat ProgramSockets 和 ServerSockets 服务器/客户端 GUI 聊天程序
【发布时间】:2013-12-16 07:00:11
【问题描述】:

我正在尝试学习套接字和 ServerSockets 在 Java 中的工作方式,因此我尝试创建一个聊天服务器,但同时使用线程来处理每个客户端。我认为我需要重新审视我的代码,因为我不知道它为什么不起作用。程序启动但客户端未连接且未创建。我相当肯定我的客户班出了点问题,但我不确定需要修复什么。任何帮助,即使只是指向有用资源的链接,将不胜感激。谢谢。

服务器代码

     package chatbox.server;

        import static java.lang.System.out;

        import java.io.IOException;
        import java.io.InputStream;
        import java.io.InputStreamReader;
        import java.io.OutputStream;
        import java.io.PrintStream;
        import java.net.ServerSocket;
        import java.net.Socket;
        import java.util.ArrayList;
        import java.util.Scanner;


     public class Server {


    public final static int DEFAULT_PORT = 5000;

    private ServerSocket socket;
    private ArrayList<Socket> clients;


    public Server(int port) throws IOException {
        System.out.println("Server is now online");
        System.out.println("port: " + port);
        this.socket = new ServerSocket(port);
        System.out.println("Listening socket established");
        System.out.println("Waiting for connections...");
        this.clients = new ArrayList<Socket>();


        while (true) {
            try {
                final Socket connection = this.socket.accept();
                this.clients.add(connection);


                Runnable incomingMsg = new Runnable() {
                    private InputStream inputStream = connection.getInputStream();
                    private InputStreamReader reader = new InputStreamReader(
                            inputStream);
                    private Scanner scanner = new Scanner(reader);

                    @Override
                    public void run() {
                        while (true) {
                            if (scanner.hasNextLine()) {
                                String msg = scanner.nextLine();
                                System.out.println("Handling message: \"" + msg
                                        + "\"");
                                notifyAllConnections(msg);
                            }
                        }
                    }

                };

                Thread thread = new Thread(incomingMsg);


                thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

                    @Override
                    public void uncaughtException(Thread thread, Throwable exc) {
                        try {
                            connection.close();
                        } catch (IOException e1) {

                            e1.printStackTrace();
                        } finally {
                            clients.remove(connection);
                            System.out.println("Removed connection");
                        }

                    }
                });
                thread.start();
                System.out.println("Added new connection");
            } catch (IOException exc) {

                System.out
                        .println("Error occurred.");
            }
        }
    }

    protected void notifyAllConnections(String msg) {
        for (Socket sock : this.clents) {
            try {
                OutputStream out = sock.getOutputStream();
                PrintStream printer = new PrintStream(out);
                printer.println(msg);
                printer.flush();
            } catch (IOException exc) {
                System.out.println("Message was not fully broadcast");
            }

        }
    }

    public static void main(String[] args) {
        try {
            Server server = new Server(
                    Server.DEFAULT_PORT);
        } catch (IOException exc) {
            System.out
                    .println("Could not create the server socket.");
            exc.printStackTrace();
            String servername = "localhost";
            try {
                new Client(servername, 5000);
            } catch (Exception ex) {
                out.println("Error" + ex.getMessage());

            }
        }
    }
    }

客户代码

     package chatbox.client

        import java.awt.event.ActionListener;

        import javax.swing.JFrame;
        import java.io.*;
        import java.util.*;
        import java.net.*;
        import javax.swing.*;
        import java.awt.*;
        import java.awt.event.*;
        import static java.lang.System.out;

        public class Client extends JFrame {

    private PrintWriter pw;
    private Scanner scanner;
    private JPanel chatAndSend;
    private JTextArea chatWindow;
    private JScrollPane mainScroll;
    private JTextArea chatText;
    private JScrollPane miniScroll;
    private JButton send;
    private Socket client;

    public Client(String servername, int port) throws Exception {

        this.client = new Socket(servername, port);
        this.scanner = new Scanner(new InputStreamReader(
                this.client.getInputStream()));
        this.pw = new PrintWriter(this.client.getOutputStream());

        makeGUI();
        new MessagesThread().start();

    }

    public void makeGUI() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        this.chatWindow = new JTextArea(10, 20);
        this.chatWindow.setEditable(false);
        this.chatWindow.setLineWrap(true);
        this.mainScroll = new JScrollPane(chatWindow,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        this.add(this.mainScroll, BorderLayout.NORTH);
        this.chatAndSend = new JPanel();
        this.chatAndSend.setLayout(new FlowLayout());
        this.chatText = new JTextArea(1, 1);
        this.chatText.setLineWrap(true);
        this.miniScroll = new JScrollPane(chatText,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        this.chatAndSend.add(this.miniScroll);
        this.send = new JButton();
        this.send.setText("SEND");
        this.send.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                pw.println(chatText.getText());
                pw.flush();
            }
        });
        this.chatAndSend.add(this.send);
        this.add(this.chatAndSend, BorderLayout.SOUTH);
        this.setVisible(true);
        this.pack();
    }

    class MessagesThread extends Thread {
        public void run() {
            String line;
            try {
                while (true) {
                    line = scanner.nextLine();
                    chatWindow.append(line + "\n");
                }
            } catch (Exception exception) {
                System.out.println(exception.getMessage());
            }
        }
    }
    }

【问题讨论】:

    标签: java multithreading swing sockets serversocket


    【解决方案1】:
    • 在Client MessagesThread类中,在while循环中,应该是while (scanner.hasNextLine()) {
    • 在同一个类中,您从后台线程追加到 JTextArea,这是您不应该做的事情。
    • 在 Client MessagesThread 类中,实现 Runnable 而不是扩展 Thread(一般建议)
    • 更好 - 使用 SwingWorker,因此您可以使用发布/处理来更新 Swing 事件线程上的 JTextArea。
    • 为了我的钱,我会先让程序在非 GUI 版本中启动并运行,然后再尝试将其放入 GUI。
    • 您的拼写错误表明代码甚至不应该编译,客户和客户怎么办,... ???这是您的真实代码吗?如果我们无法复制/粘贴您的代码并对其进行测试,我们将很难为您提供帮助。

    编辑
    我已经查看并运行了您的新代码。您是否看到您正在尝试在一个从未调用过的 catch 块中创建一个新客户端?

    最重要的是——在运行代码时使用调试器来查看代码在做什么或不做什么。也添加 println 语句(更多)。如果你这样做了,你会看到客户端的构造函数永远不会被调用,并且会知道查看你尝试调用它的代码以了解原因。

    【讨论】:

    • 首先,很抱歉错字。我一定是打字太快了。其次,我尝试了你的建议。现在,class MessagesThread implements Runnable 导致我更改 new MessagesThread.start() to MessagesThread.run() 但是客户端仍然没有连接到服务器。
    • 那么,你是说一旦我移动大括号,并在 main 方法中调用客户端而不是在 try/catch 中,一切都应该正常工作?
    • @Ashton:不,我是说我看到一个明显的粗心错误,可能永远不应该通过你的校对。您还有更多工作要做,包括线程工作。
    【解决方案2】:

    不确定这是否是您的问题之一,但我不知道在 Server 类中创建 foreach 循环是否安全,因为您可以从一个线程迭代并同时从另一个线程添加内容到列表,这可能是 foreach 循环的问题。如果我错了,请纠正我。 (或者只是从 foreach 中删除可能会损害它?)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多