Java 单服务器和多客户端的通信死锁
我是Java初学者,正在编写聊天服务器应用程序。该应用程序有助于n个客户端之间的聊天 当前问题 在我下面的代码中,Chatinterface classis是客户端类。在我打开Chatinterfaceclass的两个实例之后,当我试图通过在文本区域中输入消息进行通信时。我在另一个客户端实例窗口中没有收到消息,反之亦然。要么我的套接字无法通信,要么存在其他问题 预期产量 两个客户端都必须通信,并且消息必须显示在各自的窗口中 谁能告诉我出了什么问题,我在哪里可以更正代码 无论如何,我粘贴我的客户端和服务器代码以进行详细分析Java 单服务器和多客户端的通信死锁,java,sockets,network-programming,Java,Sockets,Network Programming,我是Java初学者,正在编写聊天服务器应用程序。该应用程序有助于n个客户端之间的聊天 当前问题 在我下面的代码中,Chatinterface classis是客户端类。在我打开Chatinterfaceclass的两个实例之后,当我试图通过在文本区域中输入消息进行通信时。我在另一个客户端实例窗口中没有收到消息,反之亦然。要么我的套接字无法通信,要么存在其他问题 预期产量 两个客户端都必须通信,并且消息必须显示在各自的窗口中 谁能告诉我出了什么问题,我在哪里可以更正代码 无论如何,我粘贴我的客户端
package stack;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
class Chatinterface implements ActionListener {
private JFrame frame;
JTextArea textArea_1;
JTextArea textArea_2;
JButton btnNewButton;
JButton btnNewButton_1;
Socket client;
BufferedReader read;
PrintWriter write;
String getmsg;
String gettext;
public Chatinterface(){
communicate();
displaygui();
}
private void communicate() {
// TODO Auto-generated method stub
try {
client = new Socket("localhost",3420);
read = new BufferedReader(new InputStreamReader(client.getInputStream()));
write = new PrintWriter(client.getOutputStream(),true);
if(getmsg!=null)
{
while(true)
{
textArea_2.setText(getmsg);
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void displaygui() {
frame = new JFrame();
frame.setResizable(false);
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SpringLayout springLayout = new SpringLayout();
frame.getContentPane().setLayout(springLayout);
textArea_1 = new JTextArea();
springLayout.putConstraint(SpringLayout.NORTH, textArea_1, 171, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, textArea_1, 10, SpringLayout.WEST, frame.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, textArea_1, -10, SpringLayout.SOUTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, textArea_1, 340, SpringLayout.WEST, frame.getContentPane());
frame.getContentPane().add(textArea_1);
textArea_2 = new JTextArea();
textArea_2.setWrapStyleWord(true);
textArea_2.setEditable(false);
springLayout.putConstraint(SpringLayout.NORTH, textArea_2, 10, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, textArea_2, 0, SpringLayout.WEST, textArea_1);
springLayout.putConstraint(SpringLayout.SOUTH, textArea_2, 160, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, textArea_2, 0, SpringLayout.EAST, textArea_1);
frame.getContentPane().add(textArea_2);
btnNewButton = new JButton("Send");
springLayout.putConstraint(SpringLayout.NORTH, btnNewButton, -76, SpringLayout.SOUTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, btnNewButton, 5, SpringLayout.EAST, textArea_1);
springLayout.putConstraint(SpringLayout.SOUTH, btnNewButton, -27, SpringLayout.SOUTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnNewButton, 82, SpringLayout.EAST, textArea_1);
frame.getContentPane().add(btnNewButton);
btnNewButton.addActionListener(this);
btnNewButton.setActionCommand("S");
btnNewButton_1 = new JButton("Logout");
springLayout.putConstraint(SpringLayout.NORTH, btnNewButton_1, 50, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, btnNewButton_1, -65, SpringLayout.EAST, btnNewButton);
springLayout.putConstraint(SpringLayout.SOUTH, btnNewButton_1, 108, SpringLayout.NORTH, frame.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnNewButton_1, 0, SpringLayout.EAST, btnNewButton);
frame.getContentPane().add(btnNewButton_1);
btnNewButton_1.addActionListener(this);
btnNewButton_1.setActionCommand("L");
frame.setVisible(true);
}
public static void main(String args[])
{
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new Chatinterface();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
@Override
public void actionPerformed(ActionEvent arg0) {
if(arg0.getActionCommand().equals("S"))
{
String gettext2;
gettext2 = textArea_1.getText();
textArea_2.append(gettext2);
textArea_1.setText("");
write.println(gettext2);
}
if(arg0.getActionCommand().equals("L")){
try {
read.close();
write.close();
client.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
下面是服务器类的代码
package stack;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.*;
public class Server1 {
public static void main(String[] args) throws Exception {
Socket s;
ServerSocket server = new ServerSocket(3420);
while(true)
{
s = server.accept();
Handler handler1 = new Handler(s);
Thread t1 = new Thread(handler1);
t1.start();
}
}
}
下面是处理程序类
package stack;
import java.io.*;
import java.net.*;
public class Handler implements Runnable {
Socket s;
String getmsg = null;
String sendmsg;
public Handler(Socket s) {
this.s = s;
}
public void run() {
try {
BufferedReader reader1;
PrintWriter writer1;
reader1 = new BufferedReader(new InputStreamReader(
s.getInputStream()));
writer1 = new PrintWriter(s.getOutputStream(), true);
sendmsg = reader1.readLine();
while (true) {
if (reader1 == null) {
s.close();
} else {
writer1.println(sendmsg);
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
您的代码很难阅读和理解。尝试使用相关的变量名。试着专注于与问题相关的代码 我不知道你的问题是什么,但我肯定这里有问题:
e.getActionCommand() == "s"
这里呢
if (e.getActionCommand() == "L")
在测试指针相等性时,这些都是不正确的,而不是内容读取更多
所以写下:
e.getActionCommand().equals("s")
及
对于任何进一步的问题:
使用调试器
使用日志
正如ben75所说,代码很难阅读,并且有一些错误。让我提供一些建议,以帮助您: 1-不要在构造函数中创建功能。这是您在Chatinterface中执行的操作。构造函数应该只创建对象。然后您可以添加一个名为execute的方法来完成这项工作
private void execute()
{
...
}
2-我还没有测试通信部分,但它应该可以在客户端和服务器之间正常通信。我运行Chatinterface,代码正确到达这一行:
write.println(gettext2);
3-您没有看到消息的错误原因是,在构造函数中,它正在调用Communication和displaygui。Communication中的代码应显示从服务器收到的消息:
if(getmsg!=null)
{
while(true)
{
textArea_2.setText(getmsg);
}
}
但这段代码在开始时只执行一次,getmsg为null,执行控制再也不会回到这段代码。
我假设您试图在客户机中创建一个不同的线程,该线程将执行此代码并进入无限循环
如果您对通信客户端服务器有疑问,可以使用Wireshark或tcpdump嗅探通信
这里没有死锁。我已经编辑了我的问题,并在上面提供了清晰的描述。我还简化了代码。
if(getmsg!=null)
{
while(true)
{
textArea_2.setText(getmsg);
}
}