所以我终于完成了大部分工作,但我陷入了困境。我有一个可以同时处理多个连接的服务器,但是消息只分别从每个客户端发送到服务器,我希望将消息发送到服务器然后推送到所有连接的客户端。
服务器
import java.io.IOException;
import java.net.ServerSocket;
public class ChatServerV2 {
public static void main(String[] args) {
int portNumber = 8890;
boolean listening = true;
try (ServerSocket serverSocket = new ServerSocket(portNumber)) {
while (listening) {
new ChatServerThread(serverSocket.accept()).start();
}
} catch (IOException e) {
System.err.println("Could not listen on port " + portNumber);
System.exit(-1);
}
}
}
SeverThread
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Scanner;
public class ChatServerThread extends Thread{
private Socket socket = null;
private List<PrintWriter> writers = new ArrayList<PrintWriter>();
public ChatServerThread(Socket socket) {
super("ChatServerThread");
this.socket = socket;
}
public void run() {
try (
PrintWriter output = new PrintWriter(socket.getOutputStream()); //opens output stream
Scanner reader = new Scanner(socket.getInputStream()); // opens the input stream
) {
writers.add(output);
// while (reader.hasNextLine())
// {
ListIterator<PrintWriter> iter = writers.listIterator();
//while(iter.hasNext()) { // while iterator is iterating
//PrintWriter s = (iter.next()); // set the current selected iterator from iter.hasNExt to variable
String msg = reader.nextLine(); // read message coming
while(iter.hasNext()) {
PrintWriter s = iter.next();
s.println(msg);
s.flush();
System.out.println("This should be what you see on your screen?");
System.out.println(msg);
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class ChatClient
{
public static final String HOST= "localhost";
public static final int PORT = 8890;
private ChatWindow window;
private Socket connection;
public static String user = "";
public ChatClient()
{
this.window = new ChatWindow(this);
try {
Socket serverConnection = null;
try {
//Connection//
serverConnection = new Socket(HOST, PORT); //Connects to the Socket
connection = serverConnection;
//Open Streams//
Scanner reader = new Scanner(serverConnection.getInputStream()); //Reads input from the
PrintWriter writer = new PrintWriter(serverConnection.getOutputStream()); //Writes to output
Scanner msg = new Scanner(System.in); //Testing loops
}
} finally {
//serverConnection.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendMessage(String message)
{
try {
PrintWriter writer = new PrintWriter(connection.getOutputStream());
writer.println(message);
writer.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void start()
{
while (true) // while program is started and running
{
try {
Scanner reader = new Scanner(connection.getInputStream());
while (reader.hasNext())
{
window.printMessage(user+ ": " + reader.nextLine());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} //Reads input from the
}
}
public static void main(String[] args)
{
ChatClient chatClient = new ChatClient();
user = Commands.getUser();
chatClient.start();
}
}
聊天窗口(已提供,我无法更改)
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret;
@SuppressWarnings("serial")
public class ChatWindow extends JFrame
{
private ChatClient client;
private JTextArea messageArea = new JTextArea(10, 32);
private JTextField inputArea = new JTextField(32);
public ChatWindow(ChatClient theClient)
{
this.client = theClient;
//when the user closes the window, make sure the user is logged out.
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
client.sendMessage("LOGOUT");
}
});
// GUI COMPONENTS ------------------------------------------
// MESSAGE AREA: All messages from all clients are displayed here
messageArea.setEditable(false);
messageArea.setBackground(Color.LIGHT_GRAY);
messageArea.setLineWrap(true);
// make sure the scroll bar stays are the bottom
DefaultCaret caret = (DefaultCaret) messageArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
// INPUT AREA: Input area where client enters text message
// The message is sent when the user presses enter
inputArea.addActionListener(new InputAreaActionListener());
Container content = getContentPane();
content.add(new JScrollPane(messageArea), BorderLayout.CENTER);
content.add(inputArea, BorderLayout.SOUTH);
setTitle("Chat Client");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
inputArea.requestFocusInWindow();
setVisible(true);
}
/**
*
* This method adds the message to the end of the message area followed by a
* new line character.
*
* @param message
*/
public void printMessage(String message)
{
messageArea.append(String.format("%s\n", message));
try
{
messageArea.setCaretPosition(messageArea.getLineStartOffset(messageArea.getLineCount() - 1));
}
catch (BadLocationException e)
{
e.printStackTrace();
}
}
private class InputAreaActionListener implements ActionListener
{
@Override
public void actionPerformed(ActionEvent e)
{
String command = e.getActionCommand();
// ask the chat client to send the message to the server
client.sendMessage(command);
inputArea.setText("");
inputArea.requestFocusInWindow();
}
}
}
所以它的工作方式,当客户端启动时,它打开一个gui,然后我可以输入消息框,它显示我输入的内容。它工作正常,但我无法弄清楚当多个客户端运行时,而不是仅将消息发送回发送它们的客户端,将它们发送到所有连接的客户端。我看到有人说使用ArrayList()来存储线程,然后使用高级的forloop来循环,但它看起来不像是在工作
有什么想法? 我无法更改提供的SendMessage()方法参数,我根本无法更改窗口。我完全手工编写Server,ServerThread,以及所有实际代码(不包括带参数的方法头文件),以便我可以更改。我无法触摸ChatWindow