[英]IllegalThreadStateException Error on Simple Chat Application using Socket Programmin, Code bellow
[英]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.