我只想制作一个服务器应用程序,它获取字符串并将它们放入 JTextArea 中。即使没有显示任何错误,我也收到两个错误。
尽管我使用了这个语句,但窗口无法关闭:
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- 如果客户端连接到服务器,整个窗口将变黑。可能是什么错误?代码如下:
客户:
public Main() {
super("Main");
setIconImage(Toolkit.getDefaultToolkit().getImage(Main.class.getResource("/images/ic.png")));
panelFields = new JPanel();
panelFields.setLayout(new BoxLayout(panelFields,BoxLayout.X_AXIS));
panelFields2 = new JPanel();
panelFields2.setLayout(new BoxLayout(panelFields2,BoxLayout.X_AXIS));
scrollPane = new JScrollPane();
panelFields.add(scrollPane);
getContentPane().add(panelFields);
getContentPane().add(panelFields2);
getContentPane().setLayout(new BoxLayout(getContentPane(),BoxLayout.Y_AXIS));
setSize(326, 264);
setVisible(true);
messagesArea = new JTextArea();
scrollPane.setViewportView(messagesArea);
messagesArea.setColumns(30);
messagesArea.setRows(10);
messagesArea.setEditable(false);
startServer = new JButton("Start");
startServer.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
socketConnection();
startServer.setEnabled(false);
}
});
panelFields.add(startServer);
}
和服务器连接:
private void socketConnection() {
try {
serverSocket = new ServerSocket(9090);
System.out.println("Listening: " + serverSocket.getLocalPort());
} catch (IOException e) {
e.printStackTrace();
}
while (true) {
try {
socket = serverSocket.accept();
dataInputStream = new DataInputStream(socket.getInputStream());
System.out.println("ip: " + socket.getInetAddress());
System.out.println("message: " + dataInputStream.readUTF());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
也许你可以告诉我,如何解决这些问题,以及如何让服务器在客户端断开连接时不会关闭套接字。我想稍后重新连接...
最佳答案
您需要在自己的线程中启动套接字监听器,并且需要添加一个关闭该线程的窗口关闭监听器。
例如:
private ServerSocket serverSocket = null;
private boolean done = false;
private void startServer() {
Thread t = new Thread(new Runnable() {
public void Run() {
socketConnection();
});
}
t.start();
}
private void socketConnection() {
try {
serverSocket = new ServerSocket(9090);
System.out.println("Listening: " + serverSocket.getLocalPort());
while (!done) {
try {
final Socket socket = serverSocket.accept();
Thread t = new Thread(new Runnable() {
public void Run() {
handle(socket);
}
});
t.start();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void handle(Socket socket) {
if (socket == null) return;
try {
dataInputStream = new DataInputStream(socket.getInputStream());
System.out.println("ip: " + socket.getInetAddress());
System.out.println("message: " + dataInputStream.readUTF());
} catch (Exception e) {
e.printStackTrace();
} finally {
if (dataInputStream != null) {
try {
dataInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void windowClosing(WindowEvent e) {
done = true;
socketServer.close();
}
你的按钮点击监听器应该调用startServer(),然后你的窗口关闭函数将设置done = true并调用socketServer.close()。
现在您有一个用于 UI 的线程、一个用于套接字服务器的线程以及一个用于与服务器的每个连接的线程。
关于Java应用程序即使 "CLOSE ON EXIT"也无法关闭,TCP服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35094602/