반응형
실행 결과
ChatServer
ChatClient 1
ChatClient 2
ChatServer
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
private static Set<ClientHandler> clients = new HashSet<>();
private static final int PORT = 5000;
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("SERVER START. Listening port " + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("New client connected: " + clientSocket);
ClientHandler clientHandler = new ClientHandler(clientSocket);
clients.add(clientHandler);
Thread ClientThread = new Thread(clientHandler);
ClientThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static class ClientHandler implements Runnable {
private Socket clientSocket;
private BufferedReader reader;
private PrintWriter writer;
public ClientHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
writer = new PrintWriter(clientSocket.getOutputStream(), true);
writer.println("Connected to server. Input Your Name: ");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
String clientName = null;
try {
boolean isFirstEntry = true;
String clientMessage;
// 클라이언트가 메시지 입력할 때 마다 수행
while ((clientMessage = reader.readLine()) != null) {
if(isFirstEntry) {
clientName = clientMessage;
isFirstEntry = false;
broadcastMessage(clientName + " has entered");
continue;
}
System.out.println(clientName + "(" + new Date() + "): " + clientMessage);
broadcastMessage(clientName + ": " + clientMessage);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
closeConnection(clientName);
}
}
private void broadcastMessage(String message) {
synchronized (clients) {
for (ClientHandler client : clients) {
client.writer.println(message);
}
}
}
private void closeConnection(String clientName) {
try {
clients.remove(this);
reader.close();
writer.close();
clientSocket.close();
System.out.println("Connection closed: " + clientSocket + " (" + clientName + ")");
broadcastMessage(clientName + " left");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
ChatClient
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class ChatClient {
private static final String SERVER_ADDRESS = "127.0.0.1";
private static final int SERVER_PORT = 5000;
private Socket socket;
private BufferedReader reader;
private PrintWriter writer;
public static void main(String[] args) {
ChatClient client = new ChatClient();
client.start();
}
public void start() {
try {
socket = new Socket(SERVER_ADDRESS, SERVER_PORT);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
writer = new PrintWriter(socket.getOutputStream(), true);
Thread receiveThread = new Thread(() -> {
receiveMessages();
});
receiveThread.start();
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = consoleReader.readLine()) != null) {
if (userInput.equalsIgnoreCase("exit")) {
writer.println(userInput);
break;
}
writer.println(userInput);
}
System.out.println("Disconnected from server");
} catch (IOException e) {
e.printStackTrace();
} finally {
closeResources();
}
}
private void receiveMessages() {
try {
String message;
while ((message = reader.readLine()) != null) {
System.out.println(message);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
closeResources();
}
}
private void closeResources() {
try {
if (writer != null)
writer.close();
if (reader != null)
reader.close();
if (socket != null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
반응형
'Java' 카테고리의 다른 글
Java 직렬화와 역직렬화: 객체 저장과 복원을 위한 기술 (0) | 2023.06.28 |
---|---|
Java java.io 기반 입출력: 입출력 스트림, 콘솔 입출력, 파일 입출력, 보조 스트림 (0) | 2023.06.26 |
Java try-wtih-resources로 자원 관리하기 (0) | 2023.06.23 |
Java 소켓 프로그래밍: 네트워크 통신을 위한 Java Socket (0) | 2023.06.23 |
Java 동기화와 비동기 처리 (0) | 2023.06.05 |