我写了一个让多个用户聊天的聊天程序。问题是客户端无法看到其他客户输入的内容。服务器运行良好,它接受多个客户端及其输入。我创建了一个ArrayList
来存储我服务器中的客户端列表,以便他们查看其他客户端输入的内容,但它似乎无法正常工作。
这是我的代码
服务器
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class myServerSocket {
int portNumber = 4434;
ServerSocket serverSocket = null;
Socket clientSocket;
ArrayList<myServerSocketRunnable> clients = new ArrayList<myServerSocketRunnable>();
public void runServer() {
try {
while(true) {
serverSocket = new ServerSocket(portNumber);
}
} catch(IOException aww) {
System.out.println(aww.getMessage());
aww.printStackTrace();
}
try {
while(true) {
clientSocket = serverSocket.accept();
myServerSocketRunnable client = new myServerSocketRunnable(clientSocket);
clients.add(client);
new Thread(new myServerSocketRunnable(clientSocket)).start();
}
} catch(IOException aww) {
System.out.println(aww.getMessage()+"\n");
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class myServerSocketRunnable extends Thread {
protected Socket clientSocket = null;
BufferedReader in;
PrintWriter out;
String username;
String message;
public myServerSocketRunnable(Socket clientSocket) {
this.clientSocket = clientSocket;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
while(true) {
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(), true);
username = in.readLine();
message = in.readLine();
System.out.println(" "+username+": "+message);
out.println(" "+username+": "+message);
out.flush();
}
} catch(IOException aww) {
System.out.println(" "+username+" has disconnected!");
out.println(" "+username+" has disconnected!");
} finally {
try {
in.close();
out.close();
} catch(IOException aww) {
aww.printStackTrace();
}
}
}
}
public class myServer {
public static void main(String[] args) {
myServerSocket call = new myServerSocket();
System.out.println("=========================================");
System.out.println("= Messenger Server =");
System.out.println("=========================================");
call.runServer();
}
}
客户端
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
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;
public class Messenger {
private static String hostName = "127.0.0.1";
private static int portNumber = 4434;
private static Socket clientSocket;
private static PrintWriter out;
private static BufferedReader in;
private static String username, content;
private static JFrame firstFrame, secondFrame;
private static JTextField userName, userField, clientTextField;
private static JTextArea clientTexts;
private static JButton talkButton, sendButton;
public static void firstGUI(Container pane) {
pane.setLayout(null);
userName = new JTextField("Username :");
userName.setBounds(10, 35, 70, 20);
userName.setEditable(false);
userField = new JTextField();
userField.setBounds(10, 55, 225, 20);
talkButton = new JButton("Talk!");
talkButton.setBounds(85, 100, 70, 35);
talkButton.setFont(new Font("Verdana", Font.PLAIN, 15));
pane.add(userName);
pane.add(userField);
pane.add(talkButton);
pane.setBackground(Color.DARK_GRAY);
talkButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
username = userField.getText();
showFrame();
talkButton.setEnabled(false);
firstFrame.dispose();
}
});
}
public static void showGUI() {
firstFrame = new JFrame("Messenger");
firstFrame.setVisible(true);
firstFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
firstFrame.setBounds(500, 100, 250, 200);
firstFrame.setResizable(false);
firstGUI(firstFrame.getContentPane());
}
public static void contentGUI(Container pane) {
pane.setLayout(null);
clientTexts = new JTextArea();
clientTexts.setEditable(false);
clientTexts.setBounds(15, 10, 465, 490);
clientTexts.setBackground(Color.WHITE);
clientTexts.setFont(new Font("Verdana", Font.PLAIN, 13));
clientTextField = new JTextField();
clientTextField.setText("");
clientTextField.setBounds(15, 525, 360, 25);
clientTextField.setBackground(Color.WHITE);
clientTextField.setFont(new Font("Verdana", Font.PLAIN, 15));
sendButton = new JButton("Send");
sendButton.setBounds(405, 519, 75, 35);
sendButton.setFont(new Font("Verdana", Font.PLAIN, 15));
pane.add(clientTexts);
pane.add(clientTextField);
pane.add(sendButton);
pane.setBackground(Color.DARK_GRAY);
sendButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
content = clientTextField.getText();
clientTextField.setText("");
new Thread(new Runnable() {
public void run() {
try {
out.println(username);
out.println(content);
out.flush();
clientTexts.append(in.readLine()+"\n");
} catch (IOException aww) {
aww.printStackTrace();
}
}
}).start();
}
});
}
public static void showFrame() {
secondFrame = new JFrame("Messenger - Client");
secondFrame.setVisible(true);
secondFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentGUI(secondFrame.getContentPane());
secondFrame.setBounds(550, 100, 500, 600);
secondFrame.setResizable(false);
}
public static void main(String[] args) {
try {
showGUI();
clientSocket = new Socket(hostName, portNumber);
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch(IOException aww) {
userField.setForeground(Color.RED);
userField.setFont(new Font("Courier new", Font.PLAIN, 13));
userField.setText("Server is not Online");
userField.setEditable(false);
talkButton.setEnabled(false);
aww.printStackTrace();
}
}
}
我想知道代码的哪一部分是错的。也许是解决问题的解决方案。
答案 0 :(得分:1)
这里有一个问题:
clientSocket = serverSocket.accept();
myServerSocketRunnable client = new myServerSocketRunnable(clientSocket);
clients.add(client);
new Thread(new myServerSocketRunnable(clientSocket)).start();
您正在创建两个 myServerSocketRunnable对象,一个添加到客户端List,另一个放在一个线程中并运行,这可能是一个严重的问题。而是为两者创建一个:
clientSocket = serverSocket.accept();
myServerSocketRunnable client = new myServerSocketRunnable(clientSocket);
clients.add(client);
// new Thread(new myServerSocketRunnable(clientSocket)).start(); // NO
new Thread(client).start(); // YES
我不知道这是否是你问题的原因,但我知道这是不对的,需要修复。另外,正如我在评论中所说,这个while (true)
循环不属于:
while(true) {
serverSocket = new ServerSocket(portNumber);
}
只需创建一次服务器套接字然后继续。
此外,您的服务器将从一个客户端收到的数据广播到所有其他客户端?我会假设你会使用你的客户端ArrayList,但我没有看到这个被使用。客户端无法神奇地相互连接,服务器必须提供粘合剂。