我正在尝试创建一个简单的聊天,它使用线程来监听传入的消息。我有一个主类,它为目前只发送一条消息的服务器打开一个套接字。我在收听传入消息时遇到问题,我无法弄清楚我做错了什么。
这是主类,对不起所有的 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,但是这两个类不应该能够写入控制台吗?为什么我从来没有达到那个代码?问题似乎出在服务器端,但是在尝试读取时不会在客户端产生一些错误吗?
感谢您提供的所有提示和意见!