package net;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Label;
import java.awt.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.JTextField;
public class ChatClient1 extends JFrame implements ActionListener, Runnable {
JButton btn1, btn2;
JTextField tf1, tf2;
TextArea ta;
JPanel p1, p2;
BufferedReader in;
PrintWriter out;
String id;
public static final int PORT = 8001;
public ChatClient1() {
setSize(350, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("MyChat 1.0");
p1 = new JPanel();
p1.setBackground(new Color(100, 200, 100));
p1.add(new Label("HOST ", Label.CENTER));
p1.add(tf1 = new JTextField("127.0.0.1", 15));
p1.add(btn1 = new JButton("Connect"));
p2 = new JPanel();
p2.setBackground(new Color(100, 200, 100));
p2.add(new Label("CHAT ", Label.CENTER));
p2.add(tf2 = new JTextField("", 15));
p2.add(btn2 = new JButton("SEND"));
tf1.addActionListener(this);
tf2.addActionListener(this);
btn1.addActionListener(this);
btn2.addActionListener(this);
add(p1, BorderLayout.NORTH);
add(ta = new TextArea());
add(p2, BorderLayout.SOUTH);
setVisible(true);
validate();
}
@Override
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == tf1 || obj == btn1 /* connecet */) {
connect(tf1.getText().trim());
tf1.setEnabled(false);
btn1.setEnabled(false);
tf2.requestFocus();
} else if (obj == tf2 || obj == btn2 /* send */) {
String str = tf2.getText().trim();
if (str.length() == 0)
return; // 서버로 전송하지 않고 메소드 빠져 나감
if (id == null) { // 최초 한번만 실행
id = str;
setTitle(getTitle() + " [" + id + "]");
ta.setText("채팅을 시작합니다\n");
}
out.println(str); // 서버 전송
tf2.setText("");
tf2.requestFocus();
}
}// --actionPerformed
@Override
// 서버로 부터 메세지가 들어오면 반응하는 기능
public void run() {
try {
while (true) {
ta.append(in.readLine() + "\n");
tf2.requestFocus();
}
} catch (Exception e) {
System.err.println("Error in run");
e.printStackTrace();
System.exit(1);
}
}// --run
public void connect(String host) {
try {
Socket sock = new Socket(host, PORT);
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream(), true);
// 서버에서 최초로 보내는 메시지 전달
ta.append(in.readLine() + "\n");
tf2.requestFocus();
} catch (Exception e) {
e.printStackTrace();
}
// Thread Start -> run 메소드 호출
new Thread(this).start();
}// --connect
public static void main(String[] args) {
new ChatClient1();
}
}
챗팅 서버
package net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
public class ChatServer1 {
public static final int PORT = 8001;
ServerSocket server;
Vector<ClientThread1> vc;
public ChatServer1() {
try {
server = new ServerSocket(PORT);
vc = new Vector<ClientThread1>();
} catch (Exception e) {
// e.printStackTrace();
System.err.println("Error in Server");
System.exit(1); // 비정상적인 종료
}
System.out.println("******************************");
System.out.println("ChatServer1 v1.0 시작되었습니다");
System.out.println("******************************");
try {
while(true) {
Socket sock = server.accept();
ClientThread1 ct = new ClientThread1(sock);
ct.start();
// 접속한 클라이언트 Socket 객체를 Vector에 저장
vc.addElement(ct);
}
} catch (Exception e) {
// e.printStackTrace();
System.out.println("Error in Socket");
}
}
// 전체 접속자에게 메세지 전달
public void sendAllMessage(String msg) {
for (int i = 0; i< vc.size(); i++) {
ClientThread1 ct = vc.get(i);
ct.sendMessage(msg);
}
}
// 접속이 끊어진 Client를 Vector에서 제거
public void removeClient(ClientThread1 ct) {
vc.remove(ct);
}
class ClientThread1 extends Thread{
Socket sock;
BufferedReader in;
PrintWriter out;
String id;
public ClientThread1(Socket sock) {
try {
this.sock = sock;
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream(), true);
// sock.toString
System.out.println(sock.toString() + "접속됨...");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
// Client에게 최초로 보내는 메세지
out.println("사용하실 아이디를 입력하세요");
// Client에서 입력한 id를 저장
id = in.readLine();
// 접속한 모든 Client에게 welcome 메세지 전달
sendAllMessage("[" + id + "]님이 입장하셨습니다.");
String line = "";
while(true) {
if(line == null)
break; // Client 접속 종료
sendAllMessage("[" + id + "]"+ line );
}
in.close();
out.close();
sock.close();
} catch (Exception e) {
// 자신의 객체를 Vector에서 제거
removeClient(this);
System.err.println(sock + "끊어짐 .......");
}
}
// Client에게 메세지 보내는 메소드
public void sendMessage(String msg) {
out.println(msg);
}
}
public static void main(String[] args) {
new ChatServer1();
}
}
package net;
public class ChatProtocol2 {
// ID, CHAT, CHATALL, MESSAGE, CHATLIST
// (C -> S) : ID: aaa
// (S -> C) CHATLIST;aaa;bbb;ccc;홍길동;
public static final String ID = "ID";
// (C -> S) CHAT:받는 아이디;메시지 ex) CHAT:bbb; 밥먹자
// (S -> C) CHAT:보내는 아이디;메시지 ex) CHAT:aaa; 밥먹자
public static final String CHAT = "CHAT";
// (C -> S) CHATALL: 메세지
// (S -> C) CHATALL:[보내는 아이디] 메세지
public static final String CHATALL = "CHATALL";
// (C -> S) MESSAGE :받는아이디;쪽지내용 ex)MESSAGE:bbb; 밥먹자
// (S -> C) MESSAGE :보내는아이디;쪽지내용 ex)MESSAGE:aaa; 밥먹자
public static final String MESSAGE = "MESSAGE";
// (S -> C) CHATLIST:aaa;bbb;ccc;홍길동'
public static final String CHATLIST = "CHATLIST";
public static final String MODE = ":";
}
ChatServer2
package net;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
public class ChatServer2 {
public static final int PORT = 8002;
ServerSocket server;
Vector<ClientThread2> vc;
public ChatServer2() {
try {
server = new ServerSocket(PORT);
vc = new Vector<ClientThread2>();
} catch (Exception e) {
System.err.println("Error in Server");
System.exit(1); // 비정상적인 종료
}
System.out.println("*******ChatServer2 v2.0*******");
System.out.println("***클라이언트 접속을 기다리고 있습니다***");
System.out.println("******************************");
try {
while (true) {
Socket sock = server.accept();
ClientThread2 ct = new ClientThread2(sock);
ct.start();
// 접속한 클라이언트 Socket 객체를 Vector에 저장
vc.addElement(ct);
}
} catch (Exception e) {
// e.printStackTrace();
System.out.println("Error in Socket");
}
}
public void sendAllMessage(String msg) {
for (int i = 0; i < vc.size(); i++) {
ClientThread2 ct = vc.get(i);
ct.sendMessage(msg);
}
}
public void removeClient(ClientThread2 ct) {
vc.remove(ct);
}
// 접속된 모든 id 리스트 리턴 ex)aaa;bbb;홍길동;강호동;
public String getIdList() {
String list = "";
for (int i = 0; i < vc.size(); i++) {
ClientThread2 ct = vc.get(i);
list += ct.id + ";";
}
return list;
}
// 매개변수 id 값으로 ClientThread2를 검색
public ClientThread2 findClient(String id) {
ClientThread2 ct = null;
for (int i = 0; i < vc.size(); i++) {
ct = vc.get(i);
if (ct.id.equals(id)) // 매개변수의 id와 ct의 id가 동일 하다면.
break;
}
return ct;
}
class ClientThread2 extends Thread {
Socket sock;
BufferedReader in;
PrintWriter out;
String id;
public ClientThread2(Socket sock) {
try {
this.sock = sock;
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream(), true);
// sock.toString
System.out.println(sock.toString() + "접속됨...");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
sendMessage("사용하실 아이디를 입력하세요");
while (true) {
String line = in.readLine();
if (line == null)
break;
else
routine(line);
}
} catch (Exception e) {
removeClient(this);
System.err.println(sock + "[" + id + "] 끊어짐...");
}
}
public void routine(String line) {
// CHATALL:오늘은 목요일입니다.
int idx = line.indexOf(ChatProtocol2.MODE);
String cmd = line.substring(0, idx); // CHATALL
String data = line.substring(idx + 1); // 오늘은 목요일입니다.
if(cmd.equals(ChatProtocol2.ID)) {
id = data;
// 새로운 접속자 추가 되었기 때문에 리스트 재전송
sendAllMessage(ChatProtocol2 .CHATLIST+
ChatProtocol2.MODE+getIdList());
// 새로운 접속자 welcome 전송
sendAllMessage(ChatProtocol2.CHATALL+
ChatProtocol2.MODE + "[" + id + "]님이 입장하였습니다.");
}else if(cmd.equals(ChatProtocol2.CHATALL)) {
sendAllMessage(ChatProtocol2.CHATALL+
ChatProtocol2.MODE + "[" + id + "]" + data);
}
}
public void sendMessage(String msg) {
out.println(msg);
}
} // -- ClientThread2
public static void main(String[] args) {
new ChatServer2();
// String str = "CHATALL:오늘은 목요일입니다.";
// int idx = str.indexOf(':');
// System.out.println(str.substring(0,idx));
// System.out.println(str.substring(idx+1));
}
}
ChatClient2
package net;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.List;
import java.awt.Panel;
import java.awt.TextArea;
import java.awt.TextField;
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 java.util.StringTokenizer;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ChatClient2 extends JFrame implements ActionListener, Runnable {
JButton bt1, bt2, bt3, bt4;
JTextField tf1, tf2, tf3;
TextArea area;
List list;
Socket sock;
BufferedReader in;
PrintWriter out;
String listTitle = "*******대화자명단*******";
boolean flag = false;
public ChatClient2() {
setSize(450, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("MyChat v2.0");
JPanel p1 = new JPanel();
p1.add(new Label("Host", Label.RIGHT));
p1.add(tf1 = new JTextField("127.0.0.1", 10));
p1.add(new Label("Port", Label.RIGHT));
p1.add(tf2 = new JTextField("8002", 5));
bt1 = new JButton("connect");
bt1.addActionListener(this);
p1.add(bt1);
add(BorderLayout.NORTH, p1);
// //////////////////////////////////////////////////////////////////////////////////////////
area = new TextArea("MyChat v2.0");
area.setBackground(Color.DARK_GRAY);
area.setForeground(Color.PINK);
area.setEditable(false);
add(BorderLayout.CENTER, area);
// /////////////////////////////////////////////////////////////////////////////////////////
JPanel p2 = new JPanel();
p2.setLayout(new BorderLayout());
list = new List();
list.add(listTitle);
p2.add(BorderLayout.CENTER, list);
JPanel p3 = new JPanel();
p3.setLayout(new GridLayout(1, 2));
bt2 = new JButton("Save");
bt2.addActionListener(this);
bt3 = new JButton("Message");
bt3.addActionListener(this);
p3.add(bt2);
p3.add(bt3);
p2.add(BorderLayout.SOUTH, p3);
add(BorderLayout.EAST, p2);
// ///////////////////////////////////////////////////////////////////////////////////////////
JPanel p4 = new JPanel();
tf3 = new JTextField("", 30);
tf3.addActionListener(this);
bt4 = new JButton("send");
bt4.addActionListener(this);
p4.add(tf3);
p4.add(bt4);
add(BorderLayout.SOUTH, p4);
setVisible(true);
validate();
}
public void run() {
try {
String host = tf1.getText().trim();
int port = Integer.parseInt(tf2.getText().trim());
connect(host, port);
// 서버 -> 사용하실 아이디를 입력하세요.
area.append(in.readLine());
while (true) {
String line = in.readLine();
if (line == null)
break;
else
routine(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}// --run
public void routine(String line) {
int idx = line.indexOf(ChatProtocol2.MODE);
String cmd = line.substring(0, idx);
String data = line.substring(idx + 1);
if (cmd.equals(ChatProtocol2.CHATLIST)) {
// data = aaa;bbb;ccc;홍길동;
list.removeAll(); // 기존에 리스트 아이템 전부 삭제
list.add(listTitle);
StringTokenizer st = new StringTokenizer(data, ";");
while(st.hasMoreElements()) {
list.add(st.nextToken());
}
} else if (cmd.equals(ChatProtocol2.CHATALL)) {
area.append(data + "\n");
}
}// --routine
public void actionPerformed(ActionEvent e) {
Object obj = e.getSource();
if (obj == bt1) {// connect
new Thread(this).start();// run메소드 호출 결과
bt1.setEnabled(false);
tf1.setEnabled(false);
tf2.setEnabled(false);
area.setText("");
} else if (obj == bt2) {// save
} else if (obj == bt3) {// message
} else if (obj == bt4 || obj == tf3) {// send
String str = tf3.getText();
if (filterMgr(str)) {
new MDialog(this, "경고", "입력하신 글자는 금지어입니다.");
return;
}
if (!flag) /* 아이디 입력 */ {
sendMessage(ChatProtocol2.ID + ChatProtocol2.MODE + str);
setTitle(getTitle() + "-" + str + "님 반갑습니다.");
area.setText("");
tf3.setText("");
tf3.requestFocus();
flag = true;
} else /* 일반 채팅 */ {
sendMessage(ChatProtocol2.CHATALL + ChatProtocol2.MODE + str);
tf3.setText("");
tf3.requestFocus();
}
}
}// --actionPerformed
public void connect(String host, int port) {
try {
sock = new Socket(host, port);
in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream(), true/* auto flush */);
} catch (Exception e) {
e.printStackTrace();
}
}// --connect
public void sendMessage(String msg) {
out.println(msg);
}
public boolean filterMgr(String msg) {
boolean flag = false;// false이면 금지어 아님
String str[] = { "바보", "개새끼", "새끼", "자바", "java" };
// msg : 하하 호호 히히
StringTokenizer st = new StringTokenizer(msg);// 생략하면 구분자는 공백
String msgs[] = new String[st.countTokens()];
for (int i = 0; i < msgs.length; i++) {
msgs[i] = st.nextToken();
}
for (int i = 0; i < str.length; i++) {
if (flag)
break;// 첫번째 for문 빠져나감.
for (int j = 0; j < msgs.length; j++) {
if (str[i].equalsIgnoreCase(msgs[j])) {
flag = true;
break; // 두번째 for문 빠져나감.
} // if
} // for2
} // for1
return flag;
}
class Message extends Frame implements ActionListener {
Button send, close;
TextField name;
TextArea ta;
String mode;// to/from
String id;
public Message(String mode) {
setTitle("쪽지보내기");
this.mode = mode;
id = list.getSelectedItem();
layset("");
validate();
}
public Message(String mode, String id, String msg) {
setTitle("쪽지읽기");
this.mode = mode;
this.id = id;
layset(msg);
validate();
}
public void layset(String msg) {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
Panel p1 = new Panel();
p1.add(new Label(mode, Label.CENTER));
name = new TextField(id, 20);
p1.add(name);
add(BorderLayout.NORTH, p1);
ta = new TextArea("");
add(BorderLayout.CENTER, ta);
ta.setText(msg);
Panel p2 = new Panel();
if (mode.equals("TO:")) {
p2.add(send = new Button("send"));
send.addActionListener(this);
}
p2.add(close = new Button("close"));
close.addActionListener(this);
add(BorderLayout.SOUTH, p2);
setBounds(200, 200, 250, 250);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == send) {
sendMessage(ChatProtocol2.MESSAGE + ":" + id + ";" + ta.getText());
}
setVisible(false);
dispose();
}
}
class MDialog extends Dialog implements ActionListener {
Button ok;
ChatClient2 ct2;
public MDialog(ChatClient2 ct2, String title, String msg) {
super(ct2, title, true);
this.ct2 = ct2;
//////////////////////////////////////////////////////////////////////////////////////////
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
/////////////////////////////////////////////////////////////////////////////////////////
setLayout(new GridLayout(2, 1));
Label label = new Label(msg, Label.CENTER);
add(label);
add(ok = new Button("확인"));
ok.addActionListener(this);
layset();
setVisible(true);
validate();
}
public void layset() {
int x = ct2.getX();
int y = ct2.getY();
int w = ct2.getWidth();
int h = ct2.getHeight();
int w1 = 150;
int h1 = 100;
setBounds(x + w / 2 - w1 / 2, y + h / 2 - h1 / 2, 200, 100);
}
public void actionPerformed(ActionEvent e) {
tf3.setText("");
dispose();
}
}
public static void main(String[] args) {
new ChatClient2();
}
}
