반응형
실행 결과
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 |