Java Day 25 네트워크(2)
19 Jan 2021 | JavaJava Day 25 네트워크(2)
-
Unicasting
- 클라이언트와 서버의 1:1 통신 개념을 unicast라고 한다.
- unicasting 채팅 구현
/** * 서버는 스레드를 생성하여 클라이언트와 통신하는 소켓을 유지해야함 * 각각의 스레드가 개별 클라이언트와 통신 할 수 있도록 구현 */ // Server import java.io.*; import java.net.*; public class UnicastServer { public UnicastServer() { ServerSocket ss = null; try { ss = new ServerSocket(5001); } catch(IOException e) { System.out.println("해당 포트가 사용중입니다."); System.exit(0); } try { while(true) { System.out.println("서버 대기중"); Socket s = ss.accept(); // 클라이언트와 채팅할 스레드 생성 UnicastServerThread thread = new UnicastServerThread(s); thread.start(); } } catch(IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new UnicastServer(); } }
// Thread import java.io.*; import java.net.*; public class UnicastServerThread extends Thread { Socket s = null; BufferedReader br = null; BufferedWriter bw = null; // 객체 생성시 서버의 소켓을 받아서 저장 public UnicastServerThread(Socket s) { this.s = s; } @Override public void run() { // 스트림 연결 try { br = new BufferedReader(new InputStreamReader(s.getInputStream())); bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); while(true) { // 클라이언트가 전달한 메세지 수신 String msg = br.readLine(); System.out.println(msg); // 클라이언트에게 메세지 전송 bw.write(msg+"\n"); bw.flush(); } } catch(IOException e) { InetAddress ip = s.getInetAddress(); String address = ip.getHostAddress(); System.out.println("["+address+"] 와의 연결이 끊어졌습니다."); } } }
// Client import java.io.*; import java.net.*; public class UnicastClient { Socket s = null; BufferedReader br = null; BufferedWriter bw = null; BufferedReader keyboard = null; public UnicastClient() { try { s = new Socket("localHost", 5001); } catch(UnknownHostException e) { System.out.println("서버를 찾을 수 없습니다."); System.exit(0); } catch(IOException e) { System.out.println("서버와 연결할 수 없습니다."); System.exit(0); } try { // keyboard와 연결된 스트림 얻기 keyboard = new BufferedReader( new InputStreamReader(System.in)); bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); br = new BufferedReader(new InputStreamReader(s.getInputStream())); // 소켓으로부터 스트림 얻기 while(true) { // 키보드 입력 System.out.print("전송할 메세지 : "); String msg = keyboard.readLine(); // 메세지 서버로 전송 bw.write(msg+"\n"); bw.flush(); // 서버에세 메세지 수신 String getMsg = br.readLine(); System.out.println("수신 메세지 : "+getMsg); } } catch(IOException e) { System.out.println("서버와의 연결이 끊어졌습니다."); System.exit(0); } } public static void main(String[] args) { new UnicastClient(); } }
-
Multicasting
- 서버와 클라이언트의 일대 다 통신을 multicast라고 한다.
- multicast는 서버가 클라이언트로부터 받은 정보를 모든 클라이언트에게 전송함으로서 서로가 정보를 공유하도록 구현한 것이다.
- multicast의 서버는 해당 클라이언트와 통신하기 위해 생성된 스레드를 저장할 Collection이 필요하다.
- multicast의 클라이언트는 자신이 서버로 전송한 정보나 다른 클라이언트가 서버로 전송한 메세지를 수신하기 위한 수신전용의 스레드가 필요하다.
- Multicasting 채팅 구현
/** * Server * 모든 클라이언트의 연결요청을 받아서 socket을 생성하고 thread를 생성한다. * 생성된 thread를 Collection에 저장한다. */ import java.io.*; import java.net.*; import java.util.*; public class MulticastServer { private ArrayList<MultiServerThread> clientList = new ArrayList<>(); private ServerSocket ss = null; public MulticastServer() { try { ss = new ServerSocket(5002); System.out.println("서버 대기중"); while(true) { Socket s = ss.accept(); InetAddress ip = s.getInetAddress(); String address = ip.getHostAddress(); System.out.println(address+" 접속"); // 스레드 객체 생성 MultiServerThread t = new MultiServerThread(clientList, s); t.start(); // 생성된 스레드를 리스트에 저장 clientList.add(t); } }catch(IOException e) { System.out.println(e.getMessage()); } } public static void main(String[] args) { new MulticastServer(); } }
// Server Thread import java.io.*; import java.net.*; import java.util.ArrayList; public class MultiServerThread extends Thread { private Socket s; private BufferedReader in; private PrintWriter out; private ArrayList<MultiServerThread> clientList; public MultiServerThread(ArrayList<MultiServerThread> clientList, Socket s) { this.s = s; this.clientList = clientList; } @Override public synchronized void run() { try { in = new BufferedReader(new InputStreamReader(s.getInputStream())); out = new PrintWriter(s.getOutputStream()); while(true) { String msg = in.readLine(); broadCasting(msg); } } catch(IOException e) { clientList.remove(this); String ip = s.getInetAddress().getHostAddress(); try { broadCasting(ip+"와의 연결이 끊어졌습니다."); } catch(IOException ioe) { ioe.printStackTrace(); } } } // 접속자 모두에게 메세지 전송 public void broadCasting(String msg) throws IOException { for (MultiServerThread t : clientList) { t.sendMsg(msg); } } // 메세지 전송 메소드 public void sendMsg(String msg) throws IOException { out.println(msg); out.flush(); } }
// Client import java.io.*; import java.net.*; public class MulticastClient { private Socket s; private BufferedReader in; private PrintWriter out; private BufferedReader keyboard; public MulticastClient() { try { s = new Socket("localhost", 5002); System.out.println("서버 접속 성공"); keyboard = new BufferedReader(new InputStreamReader(System.in)); out = new PrintWriter(s.getOutputStream(),true); in = new BufferedReader(new InputStreamReader(s.getInputStream())); MultiClientThread t = new MultiClientThread(in); t.start(); while(true) { String msg = keyboard.readLine(); out.println(msg); } } catch(UnknownHostException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } public static void main(String[] args) { new MulticastClient(); } }
// Client Thread import java.io.*; public class MultiClientThread extends Thread { private BufferedReader in; public MultiClientThread(BufferedReader in) { this.in = in; } @Override public void run() { try { while(true) { String msg = in.readLine(); System.out.println("수신 메세지 : "+msg); } } catch(IOException e) { e.printStackTrace(); } } }
참고 자료
KG아이티뱅크 자바 강의자료