1

我正在尝试创建一个简单的聊天,它使用线程来监听传入的消息。我有一个主类,它为目前只发送一条消息的服务器打开一个套接字。我在收听传入消息时遇到问题,我无法弄清楚我做错了什么。

这是主类,对不起所有的 GUI 代码,它让它很长。

package def;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;


public class GUI extends JFrame {

    private JPanel contentPane;
    private JTextField textField;

    private static JMenuBar menuBar;
    private JMenu fileMenu;
    private JMenuItem openMenu;
    private JMenuItem exitMenu;

    private Socket socket;
    private ObjectOutputStream oos;
    private ObjectInputStream ois;

    private String ipAddress;

    private JTextArea textArea;
    private String fromServer = "";


    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    GUI frame = new GUI();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public GUI() throws IOException {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 325);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        textArea = new JTextArea();
        contentPane.add(textArea, BorderLayout.NORTH);
        textArea.setPreferredSize(new Dimension(0, 230));
        textArea.setEditable(false);

        textField = new JTextField();
        textField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent arg0) {
                if(arg0.getKeyCode() ==java.awt.event.KeyEvent.VK_ENTER){
                    // TODO
                }
            }
        });
        contentPane.add(textField, BorderLayout.SOUTH);
        textField.setColumns(10);


        // Create menu item
        menuBar = new JMenuBar();
        fileMenu = new JMenu("File");
        openMenu = new JMenuItem("Open chat");
        openMenu.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                ipAddress = JOptionPane.showInputDialog("Ange IP-address: ");
                try {
                    openSocket(ipAddress);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        });

        exitMenu = new JMenuItem("Exit");
        exitMenu.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        fileMenu.add(openMenu);
        fileMenu.add(exitMenu);
        menuBar.add(fileMenu);

        setJMenuBar(menuBar); //Add the menubar
        setVisible(true);
    }

    //Open a socket to the server
    private void openSocket(String ipAddress) throws UnknownHostException, IOException {
        socket = new Socket(ipAddress, 1337);
        new ListenIncoming(socket, this).start();
        System.out.println("Socket and thread started!");
    }

    public void setMessage(String message){
        textArea.setText(message);
    }
}

菜单中的“打开聊天”按钮有一个动作监听器,它运行方法 openSocket()。在代码底部的这个方法中,我打开一个套接字并启动一个新的 ListenIncoming 线程。

这是线程代码:

    import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;

public class ListenIncoming extends Thread{

    private Socket socket;
    private ObjectInputStream ois;
    private GUI gui;


    public ListenIncoming(Socket socket, GUI gui){
        this.socket = socket;
        this.gui = gui;
    }


    @Override
    public void run() {
        try {
            ois = new ObjectInputStream(socket.getInputStream());
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        //A loop that runs forever
        while(true){
            try {
                String fromServer = ois.readObject().toString();
                System.out.println(fromServer);
                gui.setMessage(fromServer);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
}

这是发送一条消息的服务器。我希望收到“已连接”消息,但我什么也没得到,没有错误也没有异常。我不知道我的代码哪里错了。

public class Server {

    private static Scanner in;
    private static String toSend;

    public static void main(String[] args) throws IOException {
        toSend = "";
        int port = 1337;
        in = new Scanner(System.in);


        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            System.err.println("Could not listen on port: " + port);
            System.exit(1);
        }

        Socket clientSocket = null;
        try {
            clientSocket = serverSocket.accept();
        } catch (IOException e) {
            System.err.println("Could not connect.");
            System.exit(1);
        }

        ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
        ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
        String input, output;

        output = "Connected!\n";
        oos.writeObject(output);
        System.out.println("This code is reached?");

        oos.close();
        ois.close();
        clientSocket.close();
        serverSocket.close();
    }
}

当我运行程序时,我从 GUI 类中获得了打印输出,尽管我没有从 Server 类中获得调试输出。我正在使用 Eclipse,但是这两个类不应该能够写入控制台吗?为什么我从来没有达到那个代码?问题似乎出在服务器端,但是在尝试读取时不会在客户端产生一些错误吗?

感谢您提供的所有提示和意见!

4

1 回答 1

0

首先运行服务器类..然后运行你的 GUI 类(客户端)

在控制台上打印以确认服务器已启动 -

System.out.println("Server started: " + serverSocket);

以下

serverSocket = new ServerSocket(port); 

下面的行将等待客户端连接到服务器。

    socket = server.accept();

除非您无法获取服务器消息。

于 2012-10-05T15:17:54.623 回答