티스토리 뷰
반응형
//다중 채팅 프로그램
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 |
댓글