【发布时间】:2017-04-18 12:45:52
【问题描述】:
我编写了一个让多个用户聊天的聊天程序。问题是客户端无法看到其他客户端键入的内容。服务器运行良好,它接受多个客户端及其输入。我创建了一个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();
}
}
}
我想知道代码的哪一部分是错误的。也许是解决问题的解决方案。
【问题讨论】:
-
"... but it doesn't seem to be working"-- 是我们能够帮助回答的难题。可能是时候使用调试器、记录器或两者的组合来首先识别并隔离错误了。 -
将来,您应该将代码分解成小的、可测试的组件。这样就很容易找出哪些部分有效,哪些部分无效。这里每个班级的职责太多了,我们很难找出哪一部分是错的。
-
为什么会这样:
serverSocket = new ServerSocket(portNumber);在while (true)块内?不应该只调用一次吗? -
@HovercraftFullOfEels 我明白了。我以为把它放在
while允许多个客户端进入服务器 -
@mahurt:但这不是客户进入的地方,是吗?他们在它下面的适当的while循环中输入,对吧?
标签: java multithreading sockets server client