티스토리 뷰
반응형
//다중 채팅 프로그램 import java.io.*; import java.net.*; import java.awt.*; import java.awt.event.*; import java.util.Scanner; import java.util.StringTokenizer; class ChattingClient extends Frame implements ActionListener { private static final long serialVersionUID = -6754116203125986830L; Thread listenThread; // 쓰레드 Socket socket; // 클라이언트 소켓 BufferedReader reader; // 입력 스트림 BufferedWriter writer; // 출력 스트림 String serverMsg; // 서버의 메시지 String clientMsg; // 클라이언트(누리꾼) 메시지 String name; // 이름 TextArea ta; // 여러줄을 타이핑 할 수 있는 입력 컴포넌트 TextField tf; // 한줄만을 타이핑 할 수 있는 입력 컴포넌트 List list; // 컬렉션(목록) : 클라이언트(누리꾼)들의 목록 Button b; // 창닫기 버튼 Panel p1; // 패널 Panel p2; // 패널 // 생성자 : 초기화(누리꾼 닉네임, IP, 포트) public ChattingClient(String userName, String HostIP, String HostPort) throws Exception { super("["+userName+"] Cilent Window"); this.name=userName; p1 = new Panel(); p2 = new Panel(); ta = new TextArea(); // 채팅 상황 출력란 tf = new TextField(40); // 입력란 tf.addActionListener(this); // 이벤트 감지자(리스너) -> 입력란 정보 처리 list = new List(); // 클라이언트(누리꾼)들의 목록 b = new Button("Exit"); // 창닫기 버튼 // 창닫기 이벤트 핸들러 addWindowListener(new WindowAdapter(){ @Override public void windowClosing(WindowEvent e) { // TODO Auto-generated method stub e.getWindow().setVisible(false); // 창(윈도우 : Frme)을 닫다; 메모리상에서는 여전히 e.getWindow().dispose(); // 메모리에서 제거 System.exit(0); // 프로그램 정상 종료 } }); // 끝 p1.setLayout(new GridLayout(1,2)); // 채팅창의 레이아웃 구성 // 컴포넌트 -> 컨테이너 추가 p1.add(ta); p1.add(list); p2.add(tf); p2.add(b); add(p1,"Center"); // BorderLayout -> 채팅상황(채팅글 + 누리꾼들의 목록) : GridLayout add(p2,"South"); // 입력란 name = userName; // 누리꾼 이름 InetAddress realHost = InetAddress.getByName(HostIP); // IP 처리 int realPort = Integer.parseInt(HostPort); // 포트(port) 처리 socket = new Socket(realHost, realPort ); // 클라이언트 소켓을 생성 : 클라이언트당 1개씩 생성 reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); // 소켓의 정보를 입력 스트림으로 처리 writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); // 소켓의 정보를 출력스트림으로 처리 sendMessage("001"+userName+"\n"); // 메시지를 보냄. 단 "001"은 단순한 접두어(클라이언트를 의미)임 } // 메시지를 감지하는 메소드 public void listenMessage(){ SocketThread listenThread = new SocketThread(); listenThread.setDaemon(true); listenThread.start(); } // Stream/socket Close 메소드 public void closeAll(){ try { if(reader!=null) reader.close(); if(writer!=null) writer.close(); if(socket!=null) socket.close(); System.exit(0); } catch(IOException ie) { System.out.println("IO Stream 예외처리 : " + ie.getMessage()); } catch(Exception e) { System.out.println("Close 예외처리 : " + e.getMessage()); } finally { System.exit(0); } } // closeAll // 메시지 전송 메소드 public void sendMessage(String msg) { try { writer.write(msg+" \n"); writer.flush(); // Writer 출력 스트림을 초기화(비워버림) } catch(IOException ie) { System.out.println("Messaging IO 예외 처리 : " + ie.getMessage()); } catch(Exception e) { System.out.println("예외 처리 : " + e.getMessage()); } } // 액션이 발생하면 불려지는 핸들러 public void actionPerformed(ActionEvent ae) { sendMessage("002["+name+"]"+tf.getText()); // 메시지 전송 tf.setText(""); // 입력창 초기화 } // Main 메소드 public static void main(String args[]) { ChattingClient cl = null; System.out.println("클라이언트의 닉네임, 서버의 IP, 포트를 입력하세요"); Scanner scan = new Scanner(System.in); String name = scan.nextLine(); String ip = scan.nextLine(); String port = scan.nextLine(); try { // cl = new ChattingClient(args[0], args[1], args[2]); cl = new ChattingClient(name, ip, port); cl.setBounds(200,200,400,400); // 사각형 영역의 경계를 크기만큼 지정함 cl.setVisible(true); cl.listenMessage(); } catch(Exception e){ cl.closeAll(); } } // main /* * Client Thread */ class SocketThread extends Thread implements Runnable { @Override public void run() { // TODO Auto-generated method stub try { while ( (serverMsg = reader.readLine()) != null ) { //서버의 메시지를 입력 스트림(reader)에서 읽어들임 System.out.println(serverMsg); // 서버의 메시지 출력 if (serverMsg.startsWith("001")) { // 클라이언트 리스트 list.removeAll(); // 목록에서 모든 클라이언트를 제거 StringTokenizer st = new StringTokenizer(serverMsg.substring(3),"|"); while (st.hasMoreTokens()) list.add((String)st.nextToken()); // while(in) ; 클라이언트(누리꾼)목록 } else if (serverMsg.startsWith("002")) { // 채팅 ta.append(serverMsg.substring(3)+"\n"); // 출력창(textArea)에 출력 } // if } // while(out) } catch(Exception e){ System.out.println("Thread 예외처리 :" + e.getMessage()); }finally { closeAll(); } // try } // run() } // SocketThread } // ChattingClient
채팅 클라이언트 부분
결과
서버를 구축한 상태에서 채팅 클라이언트 클래스를 실행시킨 후 닉네임, IP, 포트를 입력하면
그 서버의 채팅방에 입장이 가능하다.
반응형
'IT & programming > Java' 카테고리의 다른 글
[JAVA] 논리 연산자 (0) | 2022.05.31 |
---|---|
8/23 - 채팅 소스, 클라이언트 쓰레드 부분 (0) | 2012.08.23 |
8/23 - 채팅 소스, 서버 구축 (0) | 2012.08.23 |
8/22 - I/O, 스트림, IOEx 예제문제 (0) | 2012.08.22 |
8/21 - AWT, 로그인 예제, Adapter클래스 이용 (0) | 2012.08.21 |
댓글