package Multi;
public class ChatProtocol {
public static final String ID="ID";
public static final String CHAT="CHAT";
public static final String CHATALL="CHATALL";
public static final String MESSAGE="MESSAGE";
public static final String CHATLIST="CHATLIST";
}
======================
package Multi;
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 ChatServer {
Vector<ClientThread> vc;
public ChatServer() {
vc = new Vector<ClientThread>();
ServerSocket server = null;
try {
server = new ServerSocket(8008);
} catch (Exception e) {
System.err.println("Error in ChatServer2");
e.printStackTrace();
System.exit(1);// 1은 비정상적인 종료
}
System.out.println("************************");
System.out.println("클라이언트의 접속을 기다리고 있습니다.");
System.out.println("************************");
try {
while (true) {
Socket sock = server.accept();
ClientThread ct = new ClientThread(sock);
ct.start();
vc.add(ct);
}
} catch (Exception e) {
System.err.println("Error in Socket");
e.printStackTrace();
System.exit(1);
}
}
// 접속된 모든 Client에게 메세지 전송
public void sendAllClient(String msg) {
for (int i = 0; i < vc.size(); i++) {
ClientThread ct = vc.get(i);
ct.sendMessage(msg);
}
}
// Vector에서 ClientThread를 제거
public void removeClient(ClientThread ct) {
vc.remove(ct);
}
class ClientThread extends Thread {
Socket sock;
BufferedReader in;
PrintWriter out;
String id = "익명";
public ClientThread(Socket sock) {
this.sock = sock;
}
@Override
public void run() {
try {
in = new BufferedReader(new InputStreamReader(
sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream(), true/* auto flush */);
System.out.println(sock + "접속됨....");
// 최초 클라이언트에 보내는 메세지
out.println("사용하실 아이디를 입력하세요.");
boolean done = false;
while (!done) {
String line = in.readLine();
if (line == null)
done = true;
else
routine(line);
}
} catch (Exception e) {
removeClient(this);
System.err.println(sock + "[" + id + "] 끊어짐.");
e.printStackTrace();
}
}
public void routine(String line) {
// CHATALL:오늘은 불타는 금요일.....
int idx = line.indexOf(':');
String cmd/* CHATALL */= line.substring(0, idx);
String data/* 오늘은.. */= line.substring(idx + 1);
if (cmd.equals(ChatProtocol.ID)) {
if (data != null && data.length() > 0) {
id = data;
sendAllClient(ChatProtocol.CHATLIST + ":" + getIds());
sendAllClient(ChatProtocol.CHAT + ":" + "[" + id
+ "]님 입장하였습니다.");
}
} else if (cmd.equals(ChatProtocol.CHAT)) {
// CHAT:bbb;배고프나?
idx = data.indexOf(';');
cmd = data.substring(0, idx);// bbb
data = data.substring(idx + 1);// 배고프나?
ClientThread ct = findThread(cmd/* bbb */);
if (ct != null) {
ct.sendMessage(ChatProtocol.CHAT + ":" + "[" + id/* aaa */
+ "] " + data);
} else {
sendMessage(ChatProtocol.CHAT + ":" + "[" + cmd/* bbb */
+ "] 사용자가 아닙니다.");
}
} else if (cmd.equals(ChatProtocol.CHATALL)) {
sendAllClient(ChatProtocol.CHATALL + ":" + "[" + id/* aaa */
+ "] " + data);
} else if (cmd.equals(ChatProtocol.MESSAGE)) {
// (C->S)MESSAGE:bbb;죽을래?
// (S->C)MESSAGE:aaa;죽을래?
idx = data.indexOf(';');
cmd = data.substring(0, idx);// bbb
data = data.substring(idx + 1);// 죽을래?
ClientThread ct = findThread(cmd);
if (ct != null) {
ct.sendMessage(ChatProtocol.MESSAGE + ":" + id/* aaa */
+ ";" + data);
} else {
sendMessage(ChatProtocol.CHAT + ":" + "[" + cmd/* bbb */
+ "] 사용자가 아닙니다.");
}
}
}
// 매개변수로 받은 id로 ClientThread를 찾는다.
public ClientThread findThread(String id) {
ClientThread ct = null;
for (int i = 0; i < vc.size(); i++) {
ct = vc.get(i);
if (ct.id.equals(id))
break;
}
return ct;
}
// 접속된 모든 id를 리턴(; 구분) ex)aaa;bbb;홍길동
public String getIds() {
String ids = "";
for (int i = 0; i < vc.size(); i++) {
ClientThread ct = vc.get(i);
ids += ct.id + ";";
}
return ids;
}
public void sendMessage(String msg) {
out.println(msg);
}
}
public static void main(String[] args) {
new ChatServer();
}
}
=========================
package Multi;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
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.FileWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ChatClient extends JFrame implements ActionListener, Runnable {
JButton connectBtn, saveBtn, msgBtn, sendBtn;
JTextField hostTxt, portTxt, msgTxt;
JTextArea area;
JList<String> list;
JScrollPane scroll;
JScrollBar sb;
BufferedReader in;
PrintWriter out;
Vector<String> vlist;
boolean flag = false;
String listTitle = "*******대화자명단*******";
String id;
public ChatClient() {
setTitle("MyChat 2.0");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(470, 500);
JPanel p1 = new JPanel();
p1.add(new JLabel("Host", Label.RIGHT));
p1.add(hostTxt = new JTextField("127.0.0.1", 15));
p1.add(new JLabel("Port", Label.RIGHT));
p1.add(portTxt = new JTextField(8008 + "", 8));
connectBtn = new JButton("connect");
connectBtn.addActionListener(this);
p1.add(connectBtn);
add(BorderLayout.NORTH, p1);
// //////////////////////////////////////////////////////////////////////////////////////////
area = new JTextArea("MyChat2.0");
scroll = new JScrollPane(area,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
sb = scroll.getVerticalScrollBar();
area.setBackground(Color.DARK_GRAY);
area.setForeground(Color.YELLOW);
area.setEditable(false);
add(BorderLayout.CENTER, scroll);
// /////////////////////////////////////////////////////////////////////////////////////////
JPanel p2 = new JPanel();
p2.setLayout(new BorderLayout());
vlist = new Vector<String>();
vlist.add(listTitle);
list = new JList(vlist);
p2.add(BorderLayout.CENTER, list);
JPanel p3 = new JPanel();
p3.setLayout(new GridLayout(1, 2));
saveBtn = new JButton("Save");
saveBtn.addActionListener(this);
msgBtn = new JButton("Message");
msgBtn.addActionListener(this);
p3.add(saveBtn);
p3.add(msgBtn);
p2.add(BorderLayout.SOUTH, p3);
add(BorderLayout.EAST, p2);
// ///////////////////////////////////////////////////////////////////////////////////////////
JPanel p4 = new JPanel();
msgTxt = new JTextField("", 33);
msgTxt.addActionListener(this);
sendBtn = new JButton("SEND");
sendBtn.addActionListener(this);
p4.add(msgTxt);
p4.add(sendBtn);
add(BorderLayout.SOUTH, p4);
setVisible(true);
setResizable(false);
}
public void actionPerformed(ActionEvent e) {
Object o = e.getSource();
if (connectBtn/* connect */== o) {
connect(hostTxt.getText(), Integer.parseInt(portTxt.getText()));
hostTxt.setEditable(false);
portTxt.setEditable(false);
connectBtn.setEnabled(false);
} else if (saveBtn/* save */== o) {
String saveStr = area.getText();
long mills = System.currentTimeMillis();
try {
FileWriter fw = new FileWriter("ch25/" + mills + ".txt");
fw.write(saveStr);
new SaveMsg(this);
fw.close();
} catch (Exception ex) {
ex.printStackTrace();
}
} else if (msgBtn/* message */== o) {
new Message("TO:");
} else if (sendBtn/* send */== o || msgTxt == o) {
String msg = msgTxt.getText();
if (filterMgr(msg)) {
new Waring(this);
return;
}
if (!flag/* 아이디 입력일때 */) {
// ID:aaa
id = msg;
sendMessage(ChatProtocol.ID + ":" + id);
setTitle(getTitle() + " - " + id + "님 반갑습니다.");
area.setText("");
flag = true;
} else/* 채팅일때 */{
int i = list.getSelectedIndex();
if (i == -1 || i == 0) {// 전체채팅
sendMessage(ChatProtocol.CHATALL + ":" + msg);
} else {
String rid = vlist.get(i);
sendMessage(ChatProtocol.CHAT + ":" + rid + ";" + msg);
area.append("[" + id + "]" + msg + "\n");
}
}
}
msgTxt.setText("");
msgTxt.requestFocus();
}
public boolean filterMgr(String msg) {// 오늘 밥 머 먹을까?
boolean flag = false;// false이면 금지어 아님
String str[] = { "바보", "개새끼", "새끼", "자바", "java", "주호" };
// 하하 호호 히히
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 (int j = 0; j < msgs.length; j++) {
if (str[i].equals(msgs[j])) {
flag = true;
break;
}
}
}
return flag;
}
public void sendMessage(String msg) {
out.println(msg);
}
public void run() {
try {
boolean done = false;
while (!done) {
String line = in.readLine();
if (line == null)
done = true;
else
routine(line);
sb.setValue(sb.getMaximum());
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void connect(String host, int port) {
try {
Socket sock = new Socket(host, port);
in = new BufferedReader(
new InputStreamReader(sock.getInputStream()));
out = new PrintWriter(sock.getOutputStream(), true);
area.setText(in.readLine() + "\n");
} catch (Exception e) {
System.err.println("Error in Connect");
e.printStackTrace();
System.exit(1);
}
new Thread(this).start();
}
private void routine(String line) {
int idx = line.indexOf(':');
String cmd = line.substring(0, idx);
String data = line.substring(idx + 1);
if (cmd.equals(ChatProtocol.CHAT) || cmd.equals(ChatProtocol.CHATALL)) {
area.append(data + "\n");
} else if (cmd.equals(ChatProtocol.CHATLIST)) {
list.removeAll();
vlist.removeAllElements();
// "*******대화자명단*******"
vlist.add(listTitle);
StringTokenizer st = new StringTokenizer(data, ";");
while (st.hasMoreTokens()) {
String s = st.nextToken();
if (s != null)
vlist.add(s);
}
list.setListData(vlist);
} else if (cmd.equals(ChatProtocol.MESSAGE)) {
idx = data.indexOf(';');
cmd = data.substring(0, idx);
data = data.substring(idx + 1);
new Message("FROM:", cmd, data);
}
}
class SaveMsg extends Dialog implements ActionListener {
JButton ok;
ChatClient ct2;
public SaveMsg(ChatClient ct2) {
super(ct2, "Save", true);
this.ct2 = ct2;
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
setLayout(new GridLayout(2, 1));
Label label = new Label("대화내용을 저장하였습니다.", Label.CENTER);
add(label);
add(ok = new JButton("확인"));
ok.addActionListener(this);
layset();
setVisible(true);
}
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) {
ct2.area.setText("");
setVisible(false);
dispose();
}
}
class Message extends Frame implements ActionListener {
JButton send, close;
JTextField name;
JTextArea msg;
String mode;// to/from
String id;
public Message(String mode) {
setTitle("쪽지보내기");
this.mode = mode;
id = vlist.get(list.getSelectedIndex());
layset();
}
public Message(String mode, String id, String msg) {
setTitle("쪽지읽기");
this.mode = mode;
this.id = id;
layset();
this.msg.setText(msg);
name.setEditable(false);
}
public void layset() {
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
JPanel p1 = new JPanel();
p1.add(new Label(mode, Label.CENTER));
name = new JTextField(id, 20);
p1.add(name);
add(BorderLayout.NORTH, p1);
msg = new JTextArea(10, 30);
JScrollPane scroll = new JScrollPane(msg,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
add(scroll);
JPanel p2 = new JPanel();
if (mode.equals("TO:")) {
p2.add(send = new JButton("send"));
send.addActionListener(this);
}
p2.add(close = new JButton("close"));
close.addActionListener(this);
add(BorderLayout.SOUTH, p2);
setBounds(200, 200, 300, 250);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == send) {
sendMessage(ChatProtocol.MESSAGE + ":" + id + ";"
+ msg.getText());
}
setVisible(false);
dispose();
}
}
class Waring extends Dialog implements ActionListener {
JButton ok;
ChatClient ct2;
public Waring(ChatClient ct2) {
super(ct2, "경고", true);
this.ct2 = ct2;
// ////////////////////////////////////////////////////////////////////////////////////////
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dispose();
}
});
// ///////////////////////////////////////////////////////////////////////////////////////
setLayout(new GridLayout(2, 1));
JLabel label = new JLabel("입력하신 글짜는 금지어입니다.", JLabel.CENTER);
add(label);
add(ok = new JButton("확인"));
ok.addActionListener(this);
layset();
setVisible(true);
}
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) {
ct2.msgTxt.setText("");
dispose();
}
}
public static void main(String[] args) {
new ChatClient();
}
}
'Java' 카테고리의 다른 글
InputStream / OutputStream 데이터 흐름 (0) | 2015.01.02 |
---|---|
Chat application using multi thread with vector (0) | 2014.12.30 |
Socket 통신으로 Image전송 (0) | 2014.12.29 |
KeyListener (0) | 2014.12.28 |
ArrayList (0) | 2014.12.26 |