У меня есть класс MyServer и класс Client, на MyServer у меня есть класс ClientHandler, этот поток, который я создаю, когда новый клиент хочет подключиться к серверу, и два класса ReadThread и WriteThread используются для параллельного чтения и записи.
Если я напишу «quit» на клиенте -> клиент прекратит подключение, но на сервере я все еще могу написать этому клиенту, хотя я вызываю clientSocket.close ().
MyServer:
package Tools;
import iothreads.ClientHandler;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class MyServer implements Runnable{
public final static int PORT = 6666;
private ServerSocket serverSocket = null;
private Thread serverThread = null;
private List<ClientHandler> clients = new ArrayList<>();
public MyServer() {
try {
serverSocket = new ServerSocket(PORT);
System.out.println("I'm waiting on " + InetAddress.getLocalHost().getHostAddress() + "...");
start();
} catch (IOException e) {
e.printStackTrace();
}
}
private void start() {
if(serverThread == null) {
serverThread = new Thread(this);
serverThread.start();
}
}
public void stop() {
try {
if(serverThread != null) {
serverThread.interrupt();
serverThread = null;
}
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (serverThread != null) {
try {
addClient(serverSocket.accept());
} catch (IOException e) {
e.printStackTrace();
}
}
}
private synchronized void addClient(Socket socket) throws IOException {
ClientHandler clientHandler = new ClientHandler(socket, this);
clients.add(clientHandler);
clientHandler.open();
clientHandler.start();
}
public synchronized void remove(ClientHandler client) throws IOException {
System.out.println("Bye");
clients.remove(client);
try {
if(client != null) {
client.close();
client.interrupt();
client = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public synchronized void removeAll() {
clients.forEach(clientHandler -> {
try {
clientHandler.close();
} catch (IOException e) {
e.printStackTrace();
}
});
}
}
ClientHandler
package iothreads;
import Tools.MyServer;
import iothreads.ReadThread;
import iothreads.WriteThread;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ClientHandler extends Thread {
private Socket clientSocket = null;
private WriteThread writeThread = null;
private ReadThread readThread = null;
private MyServer server = null;
private PrintWriter out = null;
private BufferedReader in = null;
private BufferedReader stdIn = null;
public ClientHandler(Socket clientSocket, MyServer server){
this.clientSocket = clientSocket;
this.server = server;
}
@Override
public void run() {
try {
writeThread = new WriteThread(this);
readThread = new ReadThread(this);
writeThread.start();
readThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getClientSocket() {
return clientSocket;
}
public MyServer getServer() {
return server;
}
public PrintWriter getOut() {
return out;
}
public BufferedReader getIn() {
return in;
}
public BufferedReader getStdIn() {
return stdIn;
}
public synchronized void open() throws IOException {
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(),true);
stdIn = new BufferedReader(new InputStreamReader(System.in));
}
public synchronized void close() throws IOException {
if (clientSocket != null) {
clientSocket.close();
clientSocket = null;
}
if (in != null) in.close();
if (out != null) out.close();
if( stdIn != null) {
stdIn.close();
}
}
}
3.ReadThread:
package iothreads;
import Tools.MyServer;
import java.io.*;
import java.net.Socket;
public class ReadThread extends Thread{
private ClientHandler client = null;
private MyServer server = null;
public ReadThread(ClientHandler client) throws IOException {
this.client = client;
this.server = client.getServer();
}
@Override
public void run() {
try (
BufferedReader in = client.getIn();
Socket clientSocket = client.getClientSocket()
) {
String inputLine;
while (((inputLine = in.readLine()) != null)) {
System.out.println("From client -> " + clientSocket.getInetAddress().getHostAddress() + ": " + inputLine);
if (inputLine.equals("quit")) {
server.remove(client);
return;
}
}
client.close();
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ MyServer.PORT + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
4.WriteThread
package iothreads;
import Tools.MyServer;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
public class WriteThread extends Thread {
private ClientHandler client = null;
private Socket clientSocket = null;
private MyServer server = null;
public WriteThread(ClientHandler client) throws IOException {
this.client = client;
this.clientSocket = client.getClientSocket();
this.server = client.getServer();
}
@Override
public void run() {
try (
PrintWriter out = client.getOut();
BufferedReader stdIn = client.getStdIn();
) {
String outputLine;
while ((outputLine = stdIn.readLine()) != null) {
System.out.println("To client -> " + clientSocket.getInetAddress().getHostAddress());
out.println(outputLine);
if (outputLine.equals("quit")){
out.println(outputLine);
server.stop();
server.removeAll();
return;
}
}
client.close();
} catch (IOException e) {
System.out.println("Exception caught when trying to listen on port "
+ MyServer.PORT + " or listening for a connection");
System.out.println(e.getMessage());
}
}
}
Клиент
package Tools;
import iothreads.ReadThread;
import iothreads.WriteThread;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client extends Thread{
private final static String MAIN_SERVER_ADDRESS = "192.168.1.115";
public final static int PORT = 6666;
private PrintWriter out = null;
private BufferedReader in = null;
private BufferedReader stdIn = null;
private Socket clientSocket = null;
private WriteThread writeThread = null;
private ReadThread readThread = null;
private Thread clientThread = null;
public Client() {
try {
clientSocket = new Socket(MAIN_SERVER_ADDRESS,PORT);
startConnection();
} catch (IOException e) {
e.printStackTrace();
}
}
public void open() throws IOException {
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out = new PrintWriter(clientSocket.getOutputStream(),true);
stdIn = new BufferedReader(new InputStreamReader(System.in));
}
private void startConnection() throws IOException {
open();
if(clientThread == null) {
clientThread = new Thread(this);
clientThread.start();
}
}
public void stopConnection() {
try {
if(clientThread != null) {
clientThread.interrupt();
clientThread = null;
}
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
System.out.println("Connected to: " + clientSocket.getLocalAddress().getHostAddress());
try {
readThread = new ReadThread(this);
writeThread = new WriteThread(this);
} catch (IOException e) {
e.printStackTrace();
}
writeThread.start();
readThread.start();
}
public void sendMessage() {
try {
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
out.println(clientSocket.getLocalAddress());
} catch (IOException e) {
e.printStackTrace();
}
}
public PrintWriter getOut() {
return out;
}
public BufferedReader getIn() {
return in;
}
public BufferedReader getStdIn() {
return stdIn;
}
public Socket getClientSocket() {
return clientSocket;
}
}