Java ServerSocket/socket 使用默认网页进行多人聊天
Java ServerSocket/socket multiple chat with default web page
嘿,我正在创建一个可以处理多个客户端到一个服务器的聊天程序。在聊天方面一切正常。我可以让 3 个客户打开并相互交谈,一切正常。但是,我也想在有人使用 URL:PORT 到他们的浏览器时放置一个小网页,让他们知道这是一个私人服务器,请继续进行下去。
我的客户端代码是这样的:
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
public class MainClient {
private Socket clientSocket;
public PrintWriter out;
public BufferedReader userInput;
private ClientReceiver clientReceiver;
private static final int SERVER_PORT = 6427;
private String line;
public static void main(String[] args) {
MainClient uiSender = new MainClient();
uiSender.go();
}
private void go() {
try {
clientSocket = new Socket("localhost", SERVER_PORT);
out = new PrintWriter(clientSocket.getOutputStream(), true);
clientReceiver = new ClientReceiver(this, clientSocket);
userInput = new BufferedReader(new InputStreamReader(System.in));
clientReceiver.start();
while (true) {
line = userInput.readLine();
if (!clientSocket.isClosed()) {
if (line != null) {
out.println(line);
if (line.equals("END")) {
clientReceiver.interrupt();
break;
}
} else {
break;
}
} else {
break;
}
}
} catch (SocketException e) {
System.out.println("Main thread socketexception");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
if (clientSocket != null) {
clientSocket.close();
}
} catch (IOException e) {
System.err.println("Failed to close.");
}
}
System.out.println("Main thread ended");
}
public class ClientReceiver extends Thread {
private Socket clientSocket;
private MainClient mainHandle;
private BufferedReader socketIn;
private String line;
public ClientReceiver(MainClient mainHandle, Socket clientSocket) {
this.mainHandle = mainHandle;
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
socketIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while (true) {
line = socketIn.readLine();
if (line != null) {
if (line.equals("END")) {
System.out.println("Server sent END message.");
clientSocket.shutdownOutput();
System.out.println("Shutted down socket output");
} else if (line.equals("CLOSE_SOCKET_INPUT")) {
clientSocket.shutdownInput();
System.out.println("Shutted down socket input");
break;
} else
System.out.println(line);
} else {
System.out.println("Server sent null. Exiting...");
break;
}
}
} catch (SocketException e) {
System.out.println("Caught SocketException");
} catch (IOException e) {
System.out.println("Caught IOException");
e.printStackTrace();
} finally {
try {
clientSocket.close();
System.out.println("Closed client socket");
} catch (IOException e) {
System.err.println("BufferedReader or socket failed to close.");
}
System.out.println("ClientReceiver thread ended.");
System.out.println("Server has shut down. Press any key to quit.");
}
}
}
}
服务器代码是:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class MainServer {
private MessageQueue messageQueue;
private ConnectionManager connectionManager;
private BufferedReader inputStream;
private MessageRetriever messageRetriever;
private int _PORT = 6427;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private ServerSocket serverSocket;
public static void main(String[] args) {
MainServer uiThread = new MainServer();
uiThread.go();
System.out.println("Main thread ended");
}
private void go() {
System.out.println("multichat server");
messageQueue = new MessageQueue();
connectionManager = new ConnectionManager(messageQueue);
messageRetriever = new MessageRetriever(messageQueue);
connectionManager.start();
messageRetriever.start();
inputStream = new BufferedReader(new InputStreamReader(System.in));
String line;
do {
try {
line = inputStream.readLine();
messageQueue.addToSendMessage(line);
if (line.equals("END")) {
connectionManager.stopListening();
messageRetriever.interrupt();
break;
}
} catch (IOException e) {
return;
}
} while (line != null);
}
public class MessageQueue {
private ArrayList<String> toSendList = new ArrayList<String>();
private LinkedList<String> receivedMessagesList = new LinkedList<String>();
private LinkedList<ClientInfo> clientList;
private boolean shutdownTriggered;
public MessageQueue() {
clientList = new LinkedList<ClientInfo>();
}
synchronized public void addToSendMessage(String message) {
toSendList.add(message);
notifyAll();
}
synchronized public List<String> retrieveToSendMessages(int index) throws InterruptedException {
while (toSendList.size() == index) {
if (!shutdownTriggered)
wait();
else
throw new InterruptedException();
}
if (index < toSendList.size()) {
return toSendList.subList(index, toSendList.size());
} else {
System.err.println("Index is " + index + ". Send List size is " + toSendList.size());
return null;
}
}
synchronized public String pollReceivedMessage() throws InterruptedException {
while (receivedMessagesList.isEmpty()) {
if (!shutdownTriggered)
wait();
else
throw new InterruptedException();
}
return receivedMessagesList.poll();
}
synchronized public void addReceivedMessage(String message) {
receivedMessagesList.push(message);
notifyAll();
}
public void addClient(ClientInfo info) {
clientList.add(info);
}
synchronized public LinkedList<ClientInfo> getClientList() {
return clientList;
}
synchronized public void changeClientInfoStatus(int port, String newStatus) {
for (ClientInfo info : clientList) {
if (info.getPort() == port) {
info.setStatus(newStatus);
break;
}
}
notifyAll();
}
public void closeClientCommunicatorInputStreams() {
for (ClientInfo info : clientList) {
info.getCommunicator().closeInputStream();
}
}
private boolean allClientInputStreamClosed() {
for (ClientInfo info : clientList) {
if (!info.getStatus().equals(ClientInfo.STATE_CLOSED_INPUTSTREAM))
return false;
}
return true;
}
private boolean allClientOutputStreamClosed() {
for (ClientInfo info : clientList) {
if (!info.getStatus().equals(ClientInfo.STATE_CLOSED_OUTPUTSTREAM))
return false;
}
return true;
}
synchronized public void waitForAllClientInputStreamClose() {
while (!allClientInputStreamClosed()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notifyAll();
}
synchronized public void waitForAllClientOutputStreamClose() {
while (!allClientOutputStreamClosed()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notifyAll();
}
synchronized public void shutdown() {
shutdownTriggered = true;
notifyAll();
}
}
public class ClientInfo {
private ClientCommunicator communicator;
private String status;
public static final String STATE_CLOSED_INPUTSTREAM = "state_closed_inputstream";
public static final String STATE_CLOSED_OUTPUTSTREAM = "state_closed_outputstream";
public ClientInfo(ClientCommunicator communicator) {
this.communicator = communicator;
_PORT = communicator.getSocket().getPort();
}
synchronized public void setStatus(String status) {
this.status = status;
notifyAll();
}
public int getPort() {
return _PORT;
}
synchronized public String getStatus() {
return status;
}
public ClientCommunicator getCommunicator() {
return communicator;
}
}
public class ClientCommunicator extends Thread {
private MessageQueue messageQueue;
private Sender sender;
private Socket socket;
public ClientCommunicator(Socket socket, MessageQueue messageQueue) {
System.out.println("Connected to new client at port " + socket.getPort() + ". Local port is " + socket.getLocalPort());
this.messageQueue = messageQueue;
this.socket = socket;
try {
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
sender = new Sender();
sender.start();
try {
while (true) {
String receivedMessage = in.readLine(); //GET / HTTP/1.1
if (receivedMessage != null)
messageQueue.addReceivedMessage(receivedMessage);
else
break;
}
} catch (SocketException e) {
// Typically this means that the socket has been closed
} catch (IOException e) {
System.err.println(e.getMessage());
}
System.out.println("ClientCommunicator thread ended.");
}
public void closeInputStream() {
if (!socket.isInputShutdown()) {
try {
socket.shutdownInput();
messageQueue.changeClientInfoStatus(socket.getPort(), ClientInfo.STATE_CLOSED_INPUTSTREAM);
} catch (IOException e) {
System.err.println("Failed to close socket input stream.");
e.printStackTrace();
}
}
}
public void closeOutputStream() {
if (!socket.isOutputShutdown()) {
try {
socket.shutdownOutput();
} catch (IOException e) {
System.err.println("Failed to close socket output stream.");
e.printStackTrace();
}
}
}
public Socket getSocket() {
return socket;
}
private class Sender extends Thread {
private int toSendMessageIndex;
@Override
public void run() {
while (true) {
try {
List<String> messages = messageQueue.retrieveToSendMessages(toSendMessageIndex);
if (messages != null) {
boolean exit = false;
for (String message : messages) {
out.println(message); //GET / HTTP/1.1
toSendMessageIndex++;
if (message.equals("CLOSE_SOCKET_INPUT")) {
closeOutputStream();
messageQueue.changeClientInfoStatus(socket.getPort(), ClientInfo.STATE_CLOSED_OUTPUTSTREAM);
exit = true;
break;
} else if (message.equals("GET / HTTP/1.1")) {
System.out.println("GET");
loadWP();
//loadWEBPage();
}
}
if (exit)
break;
} else {
System.err.println("Null messages!");
break;
}
} catch (InterruptedException e) {
break;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("ClientCommunicator.Sender thread stopped.");
}
}
}
public class ConnectionManager extends Thread {
private final int PORT = _PORT;
private MessageQueue messageQueue;
public ConnectionManager(MessageQueue messageQueue) {
this.messageQueue = messageQueue;
}
@Override
public void run() {
try {
serverSocket = new ServerSocket(PORT, 0, InetAddress.getByName("localhost"));
System.out.println("Server listening on port " + PORT);
while (true) {
socket = serverSocket.accept();
ClientCommunicator communicator = new ClientCommunicator(socket, messageQueue);
ClientInfo clientInfo = new ClientInfo(communicator);
communicator.start();
messageQueue.addClient(clientInfo);
}
} catch (SocketException e) {
// SocketException is thrown when serverSocket is closed. This
// is normal when we shut down the server.
} catch (IOException e) {
System.err.println(e.getMessage());
} finally {
System.out.println("ConnectionManager thread ended.");
}
}
public void stopListening() {
try {
messageQueue.closeClientCommunicatorInputStreams();
messageQueue.waitForAllClientInputStreamClose();
messageQueue.addToSendMessage("CLOSE_SOCKET_INPUT");
messageQueue.waitForAllClientOutputStreamClose();
System.out.println("Closing client sockets.");
for (ClientInfo info : messageQueue.getClientList()) {
Socket socket = info.getCommunicator().getSocket();
if (!socket.isClosed()) {
try {
socket.close();
} catch (IOException e) {
System.err.println("Failed to close client socket.");
}
} else {
System.err.println("Client socket is already closed.");
}
}
if (serverSocket != null) {
serverSocket.close();
System.out.println("Closed server socket.");
}
messageQueue.shutdown();
} catch (IOException e) {
System.err.println("Failed to close socket");
}
}
}
public class MessageRetriever extends Thread {
private MessageQueue messageQueue;
public MessageRetriever(MessageQueue messageQueue) {
this.messageQueue = messageQueue;
}
@Override
public void run() {
while (true) {
try {
String receivedMessage = messageQueue.pollReceivedMessage();
if (receivedMessage == null) {
System.err.println("Received null message. Terminating.");
break;
} else {
System.out.println(receivedMessage);
messageQueue.addToSendMessage(receivedMessage);
}
} catch (InterruptedException e) {
break;
}
}
System.out.println("MessageRetriever ended.");
}
}
public void loadWEBPage() {
final String newLine = "\r\n";
try {
while (true) {
try {
String request = in.readLine();
if (request == null)
continue;
while (true) {
String ignore = in.readLine();
if (ignore == null || ignore.length() == 0)
break;
}
if (!request.startsWith("GET ")
|| !(request.endsWith(" HTTP/1.0") || request.endsWith(" HTTP/1.1"))) {
out.print("HTTP/1.0 400 Bad Request" + newLine + newLine);
} else {
String response = "Hello, World!";
out.print("HTTP/1.0 200 OK" + newLine + "Content-Type: text/plain" + newLine + "Date: "
+ new Date() + newLine + "Content-length: " + response.length() + newLine + newLine
+ response);
}
out.close();
} catch (Throwable tri) {
System.err.println("Error handling request: " + tri);
}
}
} catch (Throwable tr) {
System.err.println("Could not start server: " + tr);
}
}
}
一旦我启动了套接字服务器,我就测试了聊天,它再次来回工作得很好。然后我测试了网站 http:\localhost:6427,这是我从 Eclipse 控制台获得的输出:
multichat server
Server listening on port 6427
Connected to new client at port 58833. Local port is 6427
Upgrade-Insecure-Requests: 1
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/a
png,/;q=0.8,application/signed-exchange;v=b3
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/75.0.3770.90 Safari/537.36
Connection: keep-alive
Host: localhost:6427
GET / HTTP/1.1
Exception in thread "Thread-8" java.util.ConcurrentModificationException
at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1250)
at java.util.ArrayList$SubList.listIterator(ArrayList.java:1110)
at java.util.AbstractList.listIterator(AbstractList.java:310)
at java.util.ArrayList$SubList.iterator(ArrayList.java:1106)
at MainServer$ClientCommunicator$Sender.run(MainServer.java:292)
Connected to new client at port 58834. Local port is 6427
GET
ClientCommunicator thread ended.
我曾经让它工作过,然后我尝试了其他方法,一旦它不起作用,我试图记住我对另一个脚本做了什么,唉,我忘了....
有人想指出我缺少什么才能让它再次工作吗?
在您的代码中,您遍历了消息列表,但是当发生这种情况时,其他事情会向列表中添加另一个元素或删除一个元素,因此您会得到 ConcurrentModificationException。
例如:
这行不通:
public static void main(String[] args)
{
List<Object> objectList = new ArrayList(Arrays.asList(new Object[] { "1", "2", "3"}));
int index = 0;
for (Object object : objectList)
{
System.out.println(object.toString());
objectList.remove(index);
index++;
}
}
但是,如果您使用迭代器,则此方法有效:
public static void main(String[] args)
{
List<Object> objectList = new ArrayList(Arrays.asList(new Object[] { "1", "2", "3"}));
Iterator<Object> iterator = objectList.iterator();
while (iterator.hasNext())
{
Object object = iterator.next();
System.out.println(object.toString());
iterator.remove();
}
}
嘿,我正在创建一个可以处理多个客户端到一个服务器的聊天程序。在聊天方面一切正常。我可以让 3 个客户打开并相互交谈,一切正常。但是,我也想在有人使用 URL:PORT 到他们的浏览器时放置一个小网页,让他们知道这是一个私人服务器,请继续进行下去。
我的客户端代码是这样的:
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
public class MainClient {
private Socket clientSocket;
public PrintWriter out;
public BufferedReader userInput;
private ClientReceiver clientReceiver;
private static final int SERVER_PORT = 6427;
private String line;
public static void main(String[] args) {
MainClient uiSender = new MainClient();
uiSender.go();
}
private void go() {
try {
clientSocket = new Socket("localhost", SERVER_PORT);
out = new PrintWriter(clientSocket.getOutputStream(), true);
clientReceiver = new ClientReceiver(this, clientSocket);
userInput = new BufferedReader(new InputStreamReader(System.in));
clientReceiver.start();
while (true) {
line = userInput.readLine();
if (!clientSocket.isClosed()) {
if (line != null) {
out.println(line);
if (line.equals("END")) {
clientReceiver.interrupt();
break;
}
} else {
break;
}
} else {
break;
}
}
} catch (SocketException e) {
System.out.println("Main thread socketexception");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
out.close();
if (clientSocket != null) {
clientSocket.close();
}
} catch (IOException e) {
System.err.println("Failed to close.");
}
}
System.out.println("Main thread ended");
}
public class ClientReceiver extends Thread {
private Socket clientSocket;
private MainClient mainHandle;
private BufferedReader socketIn;
private String line;
public ClientReceiver(MainClient mainHandle, Socket clientSocket) {
this.mainHandle = mainHandle;
this.clientSocket = clientSocket;
}
@Override
public void run() {
try {
socketIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
while (true) {
line = socketIn.readLine();
if (line != null) {
if (line.equals("END")) {
System.out.println("Server sent END message.");
clientSocket.shutdownOutput();
System.out.println("Shutted down socket output");
} else if (line.equals("CLOSE_SOCKET_INPUT")) {
clientSocket.shutdownInput();
System.out.println("Shutted down socket input");
break;
} else
System.out.println(line);
} else {
System.out.println("Server sent null. Exiting...");
break;
}
}
} catch (SocketException e) {
System.out.println("Caught SocketException");
} catch (IOException e) {
System.out.println("Caught IOException");
e.printStackTrace();
} finally {
try {
clientSocket.close();
System.out.println("Closed client socket");
} catch (IOException e) {
System.err.println("BufferedReader or socket failed to close.");
}
System.out.println("ClientReceiver thread ended.");
System.out.println("Server has shut down. Press any key to quit.");
}
}
}
}
服务器代码是:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class MainServer {
private MessageQueue messageQueue;
private ConnectionManager connectionManager;
private BufferedReader inputStream;
private MessageRetriever messageRetriever;
private int _PORT = 6427;
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private ServerSocket serverSocket;
public static void main(String[] args) {
MainServer uiThread = new MainServer();
uiThread.go();
System.out.println("Main thread ended");
}
private void go() {
System.out.println("multichat server");
messageQueue = new MessageQueue();
connectionManager = new ConnectionManager(messageQueue);
messageRetriever = new MessageRetriever(messageQueue);
connectionManager.start();
messageRetriever.start();
inputStream = new BufferedReader(new InputStreamReader(System.in));
String line;
do {
try {
line = inputStream.readLine();
messageQueue.addToSendMessage(line);
if (line.equals("END")) {
connectionManager.stopListening();
messageRetriever.interrupt();
break;
}
} catch (IOException e) {
return;
}
} while (line != null);
}
public class MessageQueue {
private ArrayList<String> toSendList = new ArrayList<String>();
private LinkedList<String> receivedMessagesList = new LinkedList<String>();
private LinkedList<ClientInfo> clientList;
private boolean shutdownTriggered;
public MessageQueue() {
clientList = new LinkedList<ClientInfo>();
}
synchronized public void addToSendMessage(String message) {
toSendList.add(message);
notifyAll();
}
synchronized public List<String> retrieveToSendMessages(int index) throws InterruptedException {
while (toSendList.size() == index) {
if (!shutdownTriggered)
wait();
else
throw new InterruptedException();
}
if (index < toSendList.size()) {
return toSendList.subList(index, toSendList.size());
} else {
System.err.println("Index is " + index + ". Send List size is " + toSendList.size());
return null;
}
}
synchronized public String pollReceivedMessage() throws InterruptedException {
while (receivedMessagesList.isEmpty()) {
if (!shutdownTriggered)
wait();
else
throw new InterruptedException();
}
return receivedMessagesList.poll();
}
synchronized public void addReceivedMessage(String message) {
receivedMessagesList.push(message);
notifyAll();
}
public void addClient(ClientInfo info) {
clientList.add(info);
}
synchronized public LinkedList<ClientInfo> getClientList() {
return clientList;
}
synchronized public void changeClientInfoStatus(int port, String newStatus) {
for (ClientInfo info : clientList) {
if (info.getPort() == port) {
info.setStatus(newStatus);
break;
}
}
notifyAll();
}
public void closeClientCommunicatorInputStreams() {
for (ClientInfo info : clientList) {
info.getCommunicator().closeInputStream();
}
}
private boolean allClientInputStreamClosed() {
for (ClientInfo info : clientList) {
if (!info.getStatus().equals(ClientInfo.STATE_CLOSED_INPUTSTREAM))
return false;
}
return true;
}
private boolean allClientOutputStreamClosed() {
for (ClientInfo info : clientList) {
if (!info.getStatus().equals(ClientInfo.STATE_CLOSED_OUTPUTSTREAM))
return false;
}
return true;
}
synchronized public void waitForAllClientInputStreamClose() {
while (!allClientInputStreamClosed()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notifyAll();
}
synchronized public void waitForAllClientOutputStreamClose() {
while (!allClientOutputStreamClosed()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
notifyAll();
}
synchronized public void shutdown() {
shutdownTriggered = true;
notifyAll();
}
}
public class ClientInfo {
private ClientCommunicator communicator;
private String status;
public static final String STATE_CLOSED_INPUTSTREAM = "state_closed_inputstream";
public static final String STATE_CLOSED_OUTPUTSTREAM = "state_closed_outputstream";
public ClientInfo(ClientCommunicator communicator) {
this.communicator = communicator;
_PORT = communicator.getSocket().getPort();
}
synchronized public void setStatus(String status) {
this.status = status;
notifyAll();
}
public int getPort() {
return _PORT;
}
synchronized public String getStatus() {
return status;
}
public ClientCommunicator getCommunicator() {
return communicator;
}
}
public class ClientCommunicator extends Thread {
private MessageQueue messageQueue;
private Sender sender;
private Socket socket;
public ClientCommunicator(Socket socket, MessageQueue messageQueue) {
System.out.println("Connected to new client at port " + socket.getPort() + ". Local port is " + socket.getLocalPort());
this.messageQueue = messageQueue;
this.socket = socket;
try {
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
sender = new Sender();
sender.start();
try {
while (true) {
String receivedMessage = in.readLine(); //GET / HTTP/1.1
if (receivedMessage != null)
messageQueue.addReceivedMessage(receivedMessage);
else
break;
}
} catch (SocketException e) {
// Typically this means that the socket has been closed
} catch (IOException e) {
System.err.println(e.getMessage());
}
System.out.println("ClientCommunicator thread ended.");
}
public void closeInputStream() {
if (!socket.isInputShutdown()) {
try {
socket.shutdownInput();
messageQueue.changeClientInfoStatus(socket.getPort(), ClientInfo.STATE_CLOSED_INPUTSTREAM);
} catch (IOException e) {
System.err.println("Failed to close socket input stream.");
e.printStackTrace();
}
}
}
public void closeOutputStream() {
if (!socket.isOutputShutdown()) {
try {
socket.shutdownOutput();
} catch (IOException e) {
System.err.println("Failed to close socket output stream.");
e.printStackTrace();
}
}
}
public Socket getSocket() {
return socket;
}
private class Sender extends Thread {
private int toSendMessageIndex;
@Override
public void run() {
while (true) {
try {
List<String> messages = messageQueue.retrieveToSendMessages(toSendMessageIndex);
if (messages != null) {
boolean exit = false;
for (String message : messages) {
out.println(message); //GET / HTTP/1.1
toSendMessageIndex++;
if (message.equals("CLOSE_SOCKET_INPUT")) {
closeOutputStream();
messageQueue.changeClientInfoStatus(socket.getPort(), ClientInfo.STATE_CLOSED_OUTPUTSTREAM);
exit = true;
break;
} else if (message.equals("GET / HTTP/1.1")) {
System.out.println("GET");
loadWP();
//loadWEBPage();
}
}
if (exit)
break;
} else {
System.err.println("Null messages!");
break;
}
} catch (InterruptedException e) {
break;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("ClientCommunicator.Sender thread stopped.");
}
}
}
public class ConnectionManager extends Thread {
private final int PORT = _PORT;
private MessageQueue messageQueue;
public ConnectionManager(MessageQueue messageQueue) {
this.messageQueue = messageQueue;
}
@Override
public void run() {
try {
serverSocket = new ServerSocket(PORT, 0, InetAddress.getByName("localhost"));
System.out.println("Server listening on port " + PORT);
while (true) {
socket = serverSocket.accept();
ClientCommunicator communicator = new ClientCommunicator(socket, messageQueue);
ClientInfo clientInfo = new ClientInfo(communicator);
communicator.start();
messageQueue.addClient(clientInfo);
}
} catch (SocketException e) {
// SocketException is thrown when serverSocket is closed. This
// is normal when we shut down the server.
} catch (IOException e) {
System.err.println(e.getMessage());
} finally {
System.out.println("ConnectionManager thread ended.");
}
}
public void stopListening() {
try {
messageQueue.closeClientCommunicatorInputStreams();
messageQueue.waitForAllClientInputStreamClose();
messageQueue.addToSendMessage("CLOSE_SOCKET_INPUT");
messageQueue.waitForAllClientOutputStreamClose();
System.out.println("Closing client sockets.");
for (ClientInfo info : messageQueue.getClientList()) {
Socket socket = info.getCommunicator().getSocket();
if (!socket.isClosed()) {
try {
socket.close();
} catch (IOException e) {
System.err.println("Failed to close client socket.");
}
} else {
System.err.println("Client socket is already closed.");
}
}
if (serverSocket != null) {
serverSocket.close();
System.out.println("Closed server socket.");
}
messageQueue.shutdown();
} catch (IOException e) {
System.err.println("Failed to close socket");
}
}
}
public class MessageRetriever extends Thread {
private MessageQueue messageQueue;
public MessageRetriever(MessageQueue messageQueue) {
this.messageQueue = messageQueue;
}
@Override
public void run() {
while (true) {
try {
String receivedMessage = messageQueue.pollReceivedMessage();
if (receivedMessage == null) {
System.err.println("Received null message. Terminating.");
break;
} else {
System.out.println(receivedMessage);
messageQueue.addToSendMessage(receivedMessage);
}
} catch (InterruptedException e) {
break;
}
}
System.out.println("MessageRetriever ended.");
}
}
public void loadWEBPage() {
final String newLine = "\r\n";
try {
while (true) {
try {
String request = in.readLine();
if (request == null)
continue;
while (true) {
String ignore = in.readLine();
if (ignore == null || ignore.length() == 0)
break;
}
if (!request.startsWith("GET ")
|| !(request.endsWith(" HTTP/1.0") || request.endsWith(" HTTP/1.1"))) {
out.print("HTTP/1.0 400 Bad Request" + newLine + newLine);
} else {
String response = "Hello, World!";
out.print("HTTP/1.0 200 OK" + newLine + "Content-Type: text/plain" + newLine + "Date: "
+ new Date() + newLine + "Content-length: " + response.length() + newLine + newLine
+ response);
}
out.close();
} catch (Throwable tri) {
System.err.println("Error handling request: " + tri);
}
}
} catch (Throwable tr) {
System.err.println("Could not start server: " + tr);
}
}
}
一旦我启动了套接字服务器,我就测试了聊天,它再次来回工作得很好。然后我测试了网站 http:\localhost:6427,这是我从 Eclipse 控制台获得的输出:
multichat server
Server listening on port 6427
Connected to new client at port 58833. Local port is 6427
Upgrade-Insecure-Requests: 1
Accept-Language: en-US,en;q=0.9
Accept-Encoding: gzip, deflate, br
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/a png,/;q=0.8,application/signed-exchange;v=b3
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36 Connection: keep-alive Host: localhost:6427 GET / HTTP/1.1 Exception in thread "Thread-8" java.util.ConcurrentModificationException at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1250) at java.util.ArrayList$SubList.listIterator(ArrayList.java:1110) at java.util.AbstractList.listIterator(AbstractList.java:310) at java.util.ArrayList$SubList.iterator(ArrayList.java:1106) at MainServer$ClientCommunicator$Sender.run(MainServer.java:292)
Connected to new client at port 58834. Local port is 6427
GET
ClientCommunicator thread ended.
我曾经让它工作过,然后我尝试了其他方法,一旦它不起作用,我试图记住我对另一个脚本做了什么,唉,我忘了....
有人想指出我缺少什么才能让它再次工作吗?
在您的代码中,您遍历了消息列表,但是当发生这种情况时,其他事情会向列表中添加另一个元素或删除一个元素,因此您会得到 ConcurrentModificationException。
例如: 这行不通:
public static void main(String[] args)
{
List<Object> objectList = new ArrayList(Arrays.asList(new Object[] { "1", "2", "3"}));
int index = 0;
for (Object object : objectList)
{
System.out.println(object.toString());
objectList.remove(index);
index++;
}
}
但是,如果您使用迭代器,则此方法有效:
public static void main(String[] args)
{
List<Object> objectList = new ArrayList(Arrays.asList(new Object[] { "1", "2", "3"}));
Iterator<Object> iterator = objectList.iterator();
while (iterator.hasNext())
{
Object object = iterator.next();
System.out.println(object.toString());
iterator.remove();
}
}