⚡ TCP 멀티서버
public class multi_server { public static void main(String[] args) { new server_port(); } } //멀티 포트 설정 class server_port { /* -싱글포트로 한다면? int port = 9001; server_open so = new server_open(port); //배열의 포트번호 so.start(); */ /*멀티포트*/ public server_port() { int port[] = {9001,9002,9003}; //원시배열 사용 - 해당 포트를 다 열어버리겠다 int w=0; while(w<port.length) { server_open so = new server_open(port[w]); //배열의 포트번호 so.start(); //thread 클래스의 run 메소드 실행 - 스레드 발동 w++; } } } //멀티 포트 open (Thread 이용) class server_open extends Thread{ //멀티 스레드 String ip = ""; int pt = 0; ServerSocket sk = null; Scanner sc = null; public server_open(int p) { //즉시실행 this.ip = "172.30.1.83"; this.pt = p; } @Override public void run() { //실행 try { this.sk = new ServerSocket(this.pt); //socket을 이요하여 포트 오픈 while(true) { Socket s = this.sk.accept(); //client가 접속을 할 수 있도록 반복문으로 대기 System.out.println(this.pt + "서버 오픈"); } }catch(Exception e) { System.out.println("중복된 port로 인하여 서버가 실행되지 않습니다"); } } }
⚡ Thread를 이용한 client
public class multi_client { public static void main(String[] args) { new client_port(); } } class client_port { Socket sk = null; String serverip = ""; int port = 0; public client_port() { this.serverip = "172.30.1.83"; this.port = 9001; try { this.sk = new Socket(this.serverip,this.port);//port번호 선택 - 톡 방 선택 System.out.println("서버 접속 완료!!"); Thread co = new client_open(); //Thread 메소드 호출 co.start(); //thread 클래스의 run 메소드 실행 - 스레드 발동 }catch(Exception e) { System.out.println("서버 접속 오류 발생!!"); } } } //채팅에 참여했을 때 같은 port 사용자끼리 대화시 사용되는 부분 class client_open extends Thread{ public client_open() { } @Override public void run() { } }
🌺 채팅방 만들기
송신파트,수신파트 Thread로 분리
PrintWriter : stream -> writer 자동변환 시켜줌(byte -> String)
[server]
System.out.println(this.socket.getInetAddress()); - 상대방 접속ip 출력System.out.println(this.socket.getKeepAlive()); - socket 유무 메소드(true,false)
System.out.println(this.socket.getPort()); - 접속 port 출력
⚡ server
public class net_chat_server { public static void main(String[] args) { new net_chat_server().open(); } //소켓을 유지하는 스레드 public void open() { ServerSocket ss = null; Socket sk = null; try { ss = new ServerSocket(9000); System.out.println("[*-*-채팅 서버 오픈-*-*]"); while(true) { //socket을 유지하기 위한 무한반복문 sk = ss.accept(); //유지 chatroom ch = new chatroom(sk); //Thread ch.start(); //Thread 작동 } }catch(Exception e) { System.out.println("서버 포트 충돌로 인하여 서버 가동을 중지합니다"); }finally { if(ss != null) { try { ss.close(); System.out.println("서버를 강제 종료 합니다"); }catch(Exception e) { System.out.println("서버 소켓이 완전 오류가 발생함"); System.exit(0); } } } } } //관리자가 직접 채팅 사용 가능(관리자 Scanner 가능)한 기능으로 제작시 별도의 Thread로 빼야함 //송수신역할을 하는 Tread 클래스 class chatroom extends Thread { InputStream is = null; InputStreamReader isr = null; BufferedReader br = null; OutputStream os = null; Socket socket = null; PrintWriter pw = null; //stream -> writer 자동변환 시켜줌(byte -> String) String mid = ""; //서버에 접속한 모든 사용자 리스트 메모리에 저장 static List<PrintWriter> list = new ArrayList<PrintWriter>(); public void message(String msg) { //배열에 있는 모든 사용자에게 동일한 메세지 전달 for(PrintWriter pw : this.list) { pw.println(msg); //발송 pw.flush(); //메모리 내용을 비움 } } @Override public void run() { try { this.mid = this.br.readLine(); String hello = "[ "+ this.mid +" ] 님이 입장했습니다."; System.out.println(hello); this.message(hello); while(this.br != null) { //메세지를 입력하면 작동이 되는 반복문 hello = this.br.readLine().intern(); if(hello == "나가기") { break; }else { this.message(this.mid +":" + hello); } } }catch(Exception e) { System.out.println("사용자 추가 오류 발생으로 접속이 해제됩니다"); }finally { this.message(this.mid + "님이 퇴장했습니다."); this.list.remove(this.pw); try { this.socket.close(); }catch(Exception e) { System.out.println("--채팅 서버 종료--"); } System.out.println(this.mid + "님 퇴장ㅎ"); } } public chatroom(Socket s) { this.socket = s; try { //접속에 대한 정보를 list배열에 추가 this.pw = new PrintWriter(this.socket.getOutputStream()); this.list.add(this.pw); System.out.println("채팅 참여자 : 총" + this.list.size() + "입니다"); //채팅 관련 정보 this.is = this.socket.getInputStream(); this.isr = new InputStreamReader(this.is); this.br = new BufferedReader(this.isr); System.out.println(this.socket.getInetAddress()); //상대방 접속 ip }catch(Exception e) { System.out.println("소켓 통신 오류 발생!!!"); } } }
⚡ clientpublic class net_chat_client { public static void main(String[] args) { new net_chat_client().open(); } public void open() { String ip = "172.30.1.5"; int port = 9000; try { //딱 한번만 작동 나머지는 thread로 작동 Socket sk = new Socket(ip,port); System.out.println("[** 채팅서버 접속 완료 **]"); Scanner sc = new Scanner(System.in); System.out.println("생성할 id를 입력하세요 : "); String mid = sc.nextLine(); //Tread로 값을 이관(서버에 메세지를 송수신) - 보내는 내용을 Thread로 추가 Thread th = new chat_clients(sk,mid); th.start(); //새로운 작업공간이 열림 //접속 입장시 상대방에 대한 메세지를 출력(서버쪽 내용을 출력) InputStream is = sk.getInputStream(); InputStreamReader isr = new InputStreamReader(is); //BufferedReader 사용시 //null이 아닐 경우 송수신에 대한 byte 메모리가 full이 되므로 값이 전달 안됨 BufferedReader br = new BufferedReader(isr); //수신 while(br != null) { String chat_msg = br.readLine(); //서버에서 보내준 내용과 동일할경우 종료 if(chat_msg.equals(mid+"님이 퇴장하셨습니다")) { System.out.println("채팅 프로그램 종료"); System.exit(0); //강제 종료 break; } //자신의 화면에 서버 메세지를 출력하는 역할 System.out.println(chat_msg); } sc.close(); sk.close(); }catch(Exception e) { System.out.println("소켓통신 서버 접근 오류!!"); } } } //송신 역할을 하는 Thread (수신은 x) class chat_clients extends Thread{ Socket sk = null; String mid = null; Scanner sc = null; public chat_clients(Socket s, String id) { this.sk = s; this.mid = id; this.sc = new Scanner(System.in); } @Override public void run() { try { //접속 id를 전송(첫번째 메세지) PrintStream ps = new PrintStream(this.sk.getOutputStream()); ps.println(this.mid); ps.flush(); //사용자가 입력하는 메세지를 서버로 전송 while(true) { System.out.println("채팅 메세지를 입력하세요"); String msg = this.sc.nextLine(); ps.println(msg); ps.flush(); } }catch(Exception e) { System.out.println("서버 소켓 오류 발생으로 채팅이 중지됩니다."); } } }
'CLASS > JAVA' 카테고리의 다른 글
#20-1 / 람다(lamda)코드 사용 방식 (1) | 2024.06.11 |
---|---|
#19 / Thread (class 형태 , interface 형태) (0) | 2024.05.31 |
#18-1 / 서버 - UDP (0) | 2024.05.27 |
#17 / remind3 (0) | 2024.05.24 |
#16-2 / 서버 - TCP (0) | 2024.05.23 |