실시간 채팅 프로그램 구현하기
Server
package ex3_chat;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
//둘 이상의 클라이언트가 접속하며 클라이언트간의 문자전달도 가능한 구조의 서버 구현!
public class ChatServer extends Thread {
ServerSocket ss;
ArrayList<CopyClient> list; // 복사본 클라이언트 담을 준비
public ChatServer() {
try {
list = new ArrayList<>(); // 리스트 생성
ss = new ServerSocket(3200);
System.out.println("서버 시작!");
} catch (Exception e) {
// TODO: handle exception
}
}
public static void main(String[] args) {
new ChatServer().start();
}
@Override
public void run() {
while (true) {
try {
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + "님 접속");
CopyClient cc = new CopyClient(s, this);
list.add(cc);
cc.start(); // 복사 클라이언트의 스레드를 구동
} catch (Exception e) {
// TODO: handle exception
}
}
}
public void sendMessage(String msg) {
// 접속자들은 CopyClient로 만들어져 ArrayList에 저장된 상태
try {
for (CopyClient cc : list) {
cc.out.println(msg);
}
} catch (Exception e) {
// TODO: handle exception
}
}
public void removeClient(CopyClient cc) {
list.remove(cc); // 인자로 전달된 CopyClient 객체를 리스트에서 삭제
sendMessage("====" + cc.ip + "님 퇴장====");
}
}
Client 1
package ex3_chat;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ChatClient extends JFrame implements Runnable {
// 화면 구성 객체
JTextArea area; // 채팅을 화면에 출력하는 공간
JTextField input; // 채팅을 입력하는 공간
JButton send_bt; // 채팅 전송 버튼
JPanel south_p;
// 서버 접속 객체
Socket s;
BufferedReader in;
PrintWriter out;
Thread t;
public ChatClient() {
area = new JTextArea();
this.add(area);
// BorderLayout 배치관리자로 지정된 JPanel 생성
south_p = new JPanel(new BorderLayout());
south_p.add(input = new JTextField());
south_p.add(send_bt = new JButton("보내기"), BorderLayout.EAST);
this.add(south_p, BorderLayout.SOUTH);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
out.println("xx:~X"); // 종료시 xx:~X라는 메세지 전달
}
});
send_bt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sendData(); // 서버로 메세지를 전달하기 위한 메서드
}
});
setBounds(300, 300, 400, 500);
setVisible(true);
connected(); // 서버에 접속하기 위한 메서드
t = new Thread(this);
t.start();
}
public void connected() {
try {
s = new Socket("ip 주소 입력", 3200);
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new PrintWriter(s.getOutputStream(), true);
} catch (Exception e) {
// TODO: handle exception
}
}
public static void main(String[] args) {
new ChatClient();
}
@Override
public void run() {
while (true) {
try {
String msg = in.readLine();
if (msg.equals("xx:~X")) {
break;
}
if (msg != null) {
area.append(msg + "\r\n");
}
} catch (Exception e) {
// TODO: handle exception
}
}
closed(); // 열려있는 스트림을 닫는 메서드
System.exit(0); // 프로그램 종료
}
public void sendData() {
String msg = input.getText().trim();
if (msg.length() > 0) { // 한글자라도 입력했을 때 서버로 전송
out.println(msg);
}
input.setText(""); // 텍스트필드 비우기
}
public void closed() {
try {
if (out != null)
out.close();
if (in != null)
in.close();
if (s != null)
s.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}
Client 2
package ex3_chat;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class CopyClient extends Thread {
Socket s;
BufferedReader in;
PrintWriter out;
ChatServer server;
String ip;
public CopyClient(Socket s, ChatServer server) {
this.s = s;
this.server = server;
try {
out = new PrintWriter(s.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
ip = s.getInetAddress().getHostAddress();
} catch (Exception e) {
// TODO: handle exception
}
}
@Override
public void run() {
while (true) {
try {
String msg = in.readLine();
if (msg.equals("xx:~X")) {
out.println("xx:~X");
server.removeClient(this);
break;
}
server.sendMessage(ip + " : " + msg);
} catch (Exception e) {
// TODO: handle exception
}
}
}
}
실행 결과