我是Java编程的初学者。我正在尝试构建一个聊天服务器,其中将有1个服务器和多个客户端(目前只有2个客户端)。
逻辑: 假设有2个客户A和B
当A向B发送消息时,该消息必须首先由服务器处理,然后传递给B,反之亦然。
在窗口中,来自A的消息应显示为(示例)
A:你好
B:你好
A:你好吗?
B:我没事的
问题: 当我首先运行服务器时,它成功运行 但是当我运行客户端时,窗口被卡住了,即它没有响应。
我想知道的是,如何进行上述沟通?什么是有效的代码。
请忽略UI设计。我想解决的只是上面的逻辑
请注意,您可能会发现我的代码效率低下,并且可能还有一些垃圾代码。
班级名称: Server.java
package chatserver;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;
public class Server {
Socket soc;
ServerSocket s = null;
public Server() throws IOException
{
try
{
s = new ServerSocket(6633);
while(true)
{
soc =s.accept();
ServerHandle handle = new ServerHandle(soc);
Thread t1 = new Thread(handle);
t1.start();
}
}
catch(Exception e)
{
System.out.println(e);
//should be e.printStackTrace();
}
finally
{
if(s != null)
{
s.close();
}
}
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
try {
new Server();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服务器处理程序类
class Name: ServerHandle.java
package chatserver;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
public class ServerHandle implements Runnable {
Socket s1;
BufferedReader reader;
PrintWriter write;
String msg;
public ServerHandle(Socket s1)
{
this.s1 = s1;
}
public void run()
{
try {
reader = new BufferedReader(new InputStreamReader(s1.getInputStream()));
write = new PrintWriter(new OutputStreamWriter(s1.getOutputStream()));
while((msg = reader.readLine()) != null)
{
write.write(msg);
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally
{
try {
s1.close();
reader.close();
write.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
客户类别
班级名称: Client.java
package chatserver;
import java.awt.Container;
import java.awt.FlowLayout;
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.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.*;
public class Client implements ActionListener
{
JTextArea textArea;
private JFrame frmChatWindow;
private JTextArea textArea_1;
JTextField username;
JButton submit;
JFrame j;
JFrame jf;
BufferedReader reader;
PrintWriter write;
String msg;
Socket s;
public Client() throws Exception, IOException
{
try
{
s = new Socket("localhost", 6633);
reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
write = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
j = new JFrame("PLAIN");
j.setBounds(500, 150, 300, 400);
JPanel panel = new JPanel();
j.add(panel);
GridBagLayout gb = new GridBagLayout();
panel.setLayout(gb);
GridBagConstraints c = new GridBagConstraints();
JLabel label = new JLabel("User Name");
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.NORTHWEST;
c.ipadx = 5;
c.ipady = 5;
c.insets = new Insets(7, 7, 7, 7);
panel.add(label, c);
username = new JTextField(10);
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.WEST;
c.ipadx = 5;
c.insets = new Insets(7, 7, 7, 7);
panel.add(username, c);
JLabel password = new JLabel("Password");
c.gridx = 0;
c.gridy = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.WEST;
c.ipadx = 5;
c.insets = new Insets(7, 7, 7, 7);
panel.add(password, c);
JPasswordField pass = new JPasswordField(10);
c.gridx = 1;
c.gridy = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(7, 7, 7, 7);
panel.add(pass, c);
submit = new JButton("Submit");
c.gridx = 1;
c.gridy = 6;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(7, 7, 7, 7);
panel.add(submit, c);
submit.addActionListener(this);
j.setVisible(true);
j.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
while ((msg = reader.readLine()) != null)
{
display(msg);
}
}
catch (Exception e)
{
System.out.println(e);
}
finally
{
s.close();
reader.close();
write.close();
}
}
private void display(String msg2)
{
textArea_1.append("Server" + ": " + msg2);
}
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
j.dispose();
frmChatWindow = new JFrame();
frmChatWindow.setResizable(false);
frmChatWindow.setTitle("Chat Window");
frmChatWindow.setBounds(100, 100, 316, 300);
frmChatWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SpringLayout springLayout = new SpringLayout();
frmChatWindow.getContentPane().setLayout(springLayout);
textArea = new JTextArea();
springLayout.putConstraint(SpringLayout.WEST, textArea, 10, SpringLayout.WEST, frmChatWindow.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, textArea, 31, SpringLayout.SOUTH, frmChatWindow.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, textArea, 229, SpringLayout.WEST, frmChatWindow.getContentPane());
textArea.setLineWrap(true);
frmChatWindow.getContentPane().add(textArea);
JButton btnNewButton = new JButton("Send");
springLayout.putConstraint(SpringLayout.NORTH, textArea, 0, SpringLayout.NORTH, btnNewButton);
springLayout.putConstraint(SpringLayout.SOUTH, btnNewButton, -58, SpringLayout.SOUTH, frmChatWindow.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnNewButton, -10, SpringLayout.EAST, frmChatWindow.getContentPane());
frmChatWindow.getContentPane().add(btnNewButton);
JButton btnLogout = new JButton("Logout");
springLayout.putConstraint(SpringLayout.NORTH, btnLogout, 10, SpringLayout.NORTH, frmChatWindow.getContentPane());
springLayout.putConstraint(SpringLayout.EAST, btnLogout, -10, SpringLayout.EAST, frmChatWindow.getContentPane());
frmChatWindow.getContentPane().add(btnLogout);
textArea_1 = new JTextArea();
textArea_1.setEditable(false);
textArea_1.append(null);
springLayout.putConstraint(SpringLayout.NORTH, textArea_1, 24, SpringLayout.NORTH, frmChatWindow.getContentPane());
springLayout.putConstraint(SpringLayout.WEST, textArea_1, 10, SpringLayout.WEST, frmChatWindow.getContentPane());
springLayout.putConstraint(SpringLayout.SOUTH, textArea_1, -19, SpringLayout.NORTH, textArea);
springLayout.putConstraint(SpringLayout.EAST, textArea_1, -6, SpringLayout.WEST, btnLogout);
frmChatWindow.getContentPane().add(textArea_1);
btnLogout.addActionListener(new Test2());
btnNewButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
String s = new String();
s = textArea.getText();
sendmsg(s);
getwrite();
}
});
frmChatWindow.setVisible(true);
}
private void getwrite()
{
write.write(username.getText());
}
public void sendmsg(String g)
{
textArea_1.append(username.getText() + " " + ": " + g + "\n");
}
class Test2 implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
frmChatWindow.dispose();
j.setVisible(true);
}
}
public static void main(String[] args)
{
// TODO Auto-generated method stub
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
try
{
new Client();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}
答案 0 :(得分:1)
问题是您正在读取客户端输入和写入客户端输出。基本上你发送任何客户端只发送一个Ping服务器。
<强> ServerHandler.java 强>
while((msg = reader.readLine()) != null)
{
write.write(msg);
}
这与您在客户端构造函数中初始化Socket相结合会导致UI冻结。
<强> Client.java 强>
s = new Socket("localhost", 6633);
reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
write = new PrintWriter(new OutputStreamWriter(s.getOutputStream()));
就在下面,
while ((msg = reader.readLine()) != null)
{
display(msg);
}
面向连接的(TCP),多客户端聊天服务器的设计是错误的。您需要坐下来绘制一个关于如何从头开始编写的图表。