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

+ Recent posts