I am beginner in Java and programming a chat-server application. The application facilitates chat among n number of clients
我是Java初学者并编写聊天服务器应用程序。该应用程序促进了许多客户之间的聊天
Current Problem
In my code below the Chatinterface class
is the client class. After I open my 2 instances of Chatinterface
class, when I try to communicate by entering a message in the text area. I do not receive the message in the another client instance window and vice versa. Either my socket is not communicating or there is some other problem.
当前问题在我的代码下面,Chatinterface类是客户端类。打开我的2个Chatinterfaceclass实例后,当我尝试通过在文本区域中输入消息进行通信时。我没有在另一个客户端实例窗口中收到消息,反之亦然。我的套接字没有通信或存在其他问题。
Expected Output
Both the clients must communicate and the messages must be displayed in the respective window.
客户端必须进行通信,并且必须在相应的窗口中显示消息。
Could any one tell me what's going on wrong and where can I correct my code ?
任何人都可以告诉我发生了什么问题,我在哪里可以更正我的代码?
Anyways I am pasting both my client and server code for a detailed analysis.
无论如何,我粘贴我的客户端和服务器代码进行详细分析。
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();
}
}
}
}
Here is the code for the server class
这是服务器类的代码
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();
}
}
}
Here is the handler class
这是处理程序类
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();
}
}
}
2 个解决方案
#1
2
Your code is complex to read and understand. Try to use relevant variable names. Try to focus on code relevant to the question.
您的代码阅读和理解起来很复杂。尝试使用相关的变量名称。尝试关注与问题相关的代码。
I don't know what your problem is, but I'm sure there is something wrong here :
我不知道你的问题是什么,但我确定这里有问题:
e.getActionCommand() == "s"
and here
if (e.getActionCommand() == "L")
None of those will be true (it test for pointer equality, not content) (read more here).
这些都不是真的(它测试指针相等,而不是内容)(在这里阅读更多)。
So write this :
写这个:
e.getActionCommand().equals("s")
and
if (e.getActionCommand().equals("L"))
For any further problem :
任何进一步的问题:
- use debugger
- use logs
#2
0
As said by ben75 the code is very difficult to read and has some errors. Let me provide some suggestions to be able to help you:
正如ben75所说,代码很难阅读并且有一些错误。让我提供一些建议,以便能够帮助您:
1-Do not create functionality within the constructor. This is what you do in Chatinterface. The constructor should only create the object. Then you can add a method called "execute" to do the work.
1 - 不要在构造函数中创建功能。这就是你在Chatinterface中所做的。构造函数应该只创建对象。然后,您可以添加一个名为“execute”的方法来完成工作。
private void execute()
{
...
}
2-I haven't tested the communication part but it should communicate alright between client and server. I run Chatinterface and the code reaches correctly this line:
2 - 我没有测试通信部分,但它应该在客户端和服务器之间进行通信。我运行Chatinterface,代码正确到达这一行:
write.println(gettext2);
3-The error why you don't see the message is because, in the constructor, it is calling communicate and the displaygui. The code in communicate is the one that should display the message received back form server:
3 - 您没有看到消息的错误原因是,在构造函数中,它正在调用communication和displaygui。通信中的代码应该显示从服务器返回的消息:
if(getmsg!=null)
{
while(true)
{
textArea_2.setText(getmsg);
}
}
But this code is executed only once at the beginning, getmsg is null, and execution control never comes back again to this code. I assume you are trying to create a different thread in the client that is going to execute this code and enter the infinite loop.
但是这段代码只在开头执行一次,getmsg为null,执行控制永远不会再回到这段代码。我假设您正在尝试在客户端中创建一个不同的线程来执行此代码并进入无限循环。
If you doubt about the communication client-server you can use Wireshark or tcpdump to sniff the communication.
如果您对通信客户端服务器有疑问,可以使用Wireshark或tcpdump来嗅探通信。
There is not deadlock here.
这里没有死锁。
#1
2
Your code is complex to read and understand. Try to use relevant variable names. Try to focus on code relevant to the question.
您的代码阅读和理解起来很复杂。尝试使用相关的变量名称。尝试关注与问题相关的代码。
I don't know what your problem is, but I'm sure there is something wrong here :
我不知道你的问题是什么,但我确定这里有问题:
e.getActionCommand() == "s"
and here
if (e.getActionCommand() == "L")
None of those will be true (it test for pointer equality, not content) (read more here).
这些都不是真的(它测试指针相等,而不是内容)(在这里阅读更多)。
So write this :
写这个:
e.getActionCommand().equals("s")
and
if (e.getActionCommand().equals("L"))
For any further problem :
任何进一步的问题:
- use debugger
- use logs
#2
0
As said by ben75 the code is very difficult to read and has some errors. Let me provide some suggestions to be able to help you:
正如ben75所说,代码很难阅读并且有一些错误。让我提供一些建议,以便能够帮助您:
1-Do not create functionality within the constructor. This is what you do in Chatinterface. The constructor should only create the object. Then you can add a method called "execute" to do the work.
1 - 不要在构造函数中创建功能。这就是你在Chatinterface中所做的。构造函数应该只创建对象。然后,您可以添加一个名为“execute”的方法来完成工作。
private void execute()
{
...
}
2-I haven't tested the communication part but it should communicate alright between client and server. I run Chatinterface and the code reaches correctly this line:
2 - 我没有测试通信部分,但它应该在客户端和服务器之间进行通信。我运行Chatinterface,代码正确到达这一行:
write.println(gettext2);
3-The error why you don't see the message is because, in the constructor, it is calling communicate and the displaygui. The code in communicate is the one that should display the message received back form server:
3 - 您没有看到消息的错误原因是,在构造函数中,它正在调用communication和displaygui。通信中的代码应该显示从服务器返回的消息:
if(getmsg!=null)
{
while(true)
{
textArea_2.setText(getmsg);
}
}
But this code is executed only once at the beginning, getmsg is null, and execution control never comes back again to this code. I assume you are trying to create a different thread in the client that is going to execute this code and enter the infinite loop.
但是这段代码只在开头执行一次,getmsg为null,执行控制永远不会再回到这段代码。我假设您正在尝试在客户端中创建一个不同的线程来执行此代码并进入无限循环。
If you doubt about the communication client-server you can use Wireshark or tcpdump to sniff the communication.
如果您对通信客户端服务器有疑问,可以使用Wireshark或tcpdump来嗅探通信。
There is not deadlock here.
这里没有死锁。