1:1 채팅을 조금 바꾼 다대다, N:M 멀티 채팅이다.
전과 다른점으로는 클라이언트와 서버에 사용할 Receiver, Sender 따로 있는 점이다.
서버 기능을 가지고 있는 ServerManager 클래스
package chap12.exam05.multichat; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; public class ServerManager extends Thread { Socket socket; DataInputStream in; DataOutputStream out; // 서버이기에 in 먼저 일어남 public ServerManager(Socket socket) throws IOException { this.socket = socket; in= new DataInputStream(socket.getInputStream()); sendMsg(socket.getPort() + "님이 입장 하였습니다."); } @Override public void run() { // 서버는 메시지를 감지해야 하므로 in을 이용 while(in != null) { try { sendMsg(socket.getPort()+"> " + in.readUTF()); } catch (IOException e) { e.printStackTrace(); } } try { in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } public void sendMsg(String msg) throws IOException { // MultiServer의 List에서 소켓 리스트를 받아옴 System.out.println(msg); for(Socket soc : MultiServer.list) { out = new DataOutputStream(soc.getOutputStream()); out.writeUTF(msg); out.flush(); } } }
ServerManager를 불러오는 MultiServer
package chap12.exam05.multichat; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class MultiServer { static ArrayList<Socket> list = new ArrayList<>(); public static void main(String[] args) throws IOException { ServerManager manager; Socket socket; ServerSocket server = new ServerSocket(5252); System.out.println("서버 실행 중"); while(true) { socket = server.accept(); // 소켓을 기다림 list.add(socket); // 추가 manager = new ServerManager(socket); manager.start(); } } }
다음으로는 Client에 필요한 클래스와 메인 클라이언트
Sender
package chap12.exam05.multichat; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.util.Scanner; public class ClientSender extends Thread { Socket socket; DataOutputStream out; public ClientSender(Socket socket) throws IOException { // 초기화와 동시에 스트림도 잡아주면 효율적 this.socket = socket; out = new DataOutputStream(socket.getOutputStream()); // socket.getOutputStream을 그대로 형변환 해도 된다. } @Override public void run() { while(out != null) { System.out.print("당신>"); Scanner scan = new Scanner(System.in); try { out.writeUTF(scan.nextLine()); out.flush(); } catch (IOException e) { e.printStackTrace(); } } try { out.close(); } catch (IOException e) { e.printStackTrace(); } } }
Receiver
package chap12.exam05.multichat; import java.io.DataInputStream; import java.io.IOException; import java.net.Socket; public class ClientReceiver extends Thread { Socket socket; DataInputStream in; public ClientReceiver(Socket socket) throws IOException { this.socket = socket; in = new DataInputStream(socket.getInputStream()); // Sender와 크게 차이 없음 } @Override public void run() { while(in != null) { try { System.out.println(in.readUTF()); } catch (IOException e) { e.printStackTrace(); } } try { in.close(); } catch (IOException e) { e.printStackTrace(); } } }
실질적으로 동작할 Main MultiClient
package chap12.exam05.multichat; import java.net.Socket; public class MultiClient { public static void main(String[] args) throws Exception { Socket socket = new Socket("여기에 IP를 입력해야 정상적으로 동작해요", 5252); System.out.println("연결 성공"); ClientReceiver receiver = new ClientReceiver(socket); ClientSender sender = new ClientSender(socket); receiver.start(); sender.start(); } }
8번째 줄에 접속할 대상의 IP를 입력해주어야 하고 1개의 컴퓨터로 테스트 할 경우
대상 Server가 자기 자신이므로 자신의 IP를 입력하면 된다.
그리고 서버는 이클립스에서 실행하고
클라이언트를 따로 실행해야 하는데
https://qdgbjsdnb.tistory.com/79 를 참조하여 cmd에서 클라이언트를 작동해보자.
'개념 및 코딩 > 10.네트워크' 카테고리의 다른 글
[JAVA]10-06.File Sender, Receiver (0) | 2018.09.27 |
---|---|
[JAVA]10-06.UDP, Datagram (0) | 2018.09.27 |
[JAVA]10-04.1:1 Chat Server, Client (0) | 2018.09.27 |
[JAVA]10-03.Echo Server, Client (0) | 2018.09.27 |
[JAVA]10-02.TCP Server, Client (0) | 2018.09.27 |