03. 멀티스레드를 이용한 에코 서버
1. 멀티스레드 에코 서버 프로그래밍
import java.net.*;
import java.io.*;
public class EchoThreadServer {
public static void main(String[] args){
try {
ServerSocket server = new ServerSocket(10001);
System.out.println("접속을 기다립니다.");
while(true){
Socket socket = server.accept();
EchoThread ethr = new EchoThread(socket);
ethr.start();
}
} catch (Exception e) {
System.out.println(e);
}
}
}
class EchoThread extends Thread{
private Socket sock;
public EchoThread(Socket socke){
this.sock = socke;
}
public void run(){
try{
InetAddress inetAddr = sock.getInetAddress();
System.out.println(inetAddr.getHostAddress() + "로 부터 접속했습니다.");
OutputStream out = sock.getOutputStream();
InputStream in = sock.getInputStream();
PrintWriter pw = new PrintWriter(new OutputStreamWriter(out));
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = null;
while((line = br.readLine()) != null){
System.out.println("클라이언트로부터 전송받은 문자열 : "+line);
pw.println(line);
pw.flush();
}
pw.close();
br.close();
sock.close();
}catch(Exception ex){
System.out.println(ex);
}
}
}
05. ChatServer, Client
import java.net.*;
import java.io.*;
import java.util.*;
public class ChatServer {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(10001);
System.out.println("접속을 기다립니다.");
HashMap hm = new HashMap();
while(true) {
Socket sock = server.accept();
ChatThread chatthread = new ChatThread(sock, hm);
chatthread.start();
}
}catch(Exception e) {
System.out.println(e);
}
}
}
class ChatThread extends Thread {
private Socket sock;
private String id;
private BufferedReader br;
private HashMap hm;
private boolean initFlag = false;
public ChatThread(Socket sock, HashMap hm) {
this.sock = sock;
this.hm = hm;
try {
PrintWriter pw = new PrintWriter (new OutputStreamWriter(sock.getOutputStream()));
br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
id = br.readLine();
broadcast(id + "님이 접속했습니다.");
System.out.println("접속한 사용자의 아이디는 "+id+"입니다.");
synchronized(hm) {
hm.put(this.id, pw);
}
initFlag = true;
}catch(Exception ex) {
System.out.println(ex);
}
}
public void run() {
try{
String line = null;
while((line = br.readLine()) != null) {
if(line.equals("/quit")) break;
if(line.indexOf("/to ") == 0){
sendmsg(line);
} else {
broadcast(id+" : "+line);
}
}
}catch(Exception ex) {
System.out.println(ex);
}finally{
synchronized(hm){
hm.remove(id);
}
broadcast(id + " 님이 접속 종료했습니다.");
try{
if(sock != null) sock.close();
}catch(Exception ex){}
}
}
public void sendmsg(String msg){
int start = msg.indexOf(" ") +1;
int end = msg.indexOf(" ", start);
if(end != -1) {
String to = msg.substring(start, end);
String msg2 = msg.substring(end+1);
Object obj = hm.get(to);
if(obj != null){
PrintWriter pw = (PrintWriter) obj;
pw.println(id + " 님이 다음의 귓속말을 보내셨습니다 : "+msg2);
pw.flush();
}
}
}
public void broadcast(String msg){
synchronized(hm) {
Collection collection = hm.values();
Iterator iter = collection.iterator();
while(iter.hasNext()){
PrintWriter pw = (PrintWriter)iter.next();
pw.println(msg);
pw.flush();
}
}
}
}
import java.net.*;
import java.io.*;
public class ChatClient {
public static void main(String[] args){
if(args.length != 2){
System.out.println("사용법 : java ChatClient id 접속할 서버 ip");
System.exit(1);
}
Socket sock = null;
BufferedReader br = null;
PrintWriter pw = null;
boolean endflag = false;
try{
sock = new Socket(args[1], 10001);
pw = new PrintWriter(new OutputStreamWriter(sock.getOutputStream()));
br = new BufferedReader(new InputStreamReader(sock.getInputStream()));
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
pw.println(args[0]);
pw.flush();
InputThread it = new InputThread(sock, br);
it.start();
String line = null;
while((line = keyboard.readLine()) != null){
pw.println(line);
pw.flush();
if(line.equals("/quit")){
endflag = true;
break;
}
}
System.out.println("클라이언트의 접속을 종료합니다.");
}catch(Exception ex) {
if(!endflag){
System.out.println(ex);
}
}finally{
try{
if(pw != null) pw.close();
}catch(Exception ex){}
try{
if(br != null) br.close();
}catch(Exception ex){}
try{
if(sock != null) sock.close();
}catch(Exception ex){}
}
}
}
class InputThread extends Thread {
private Socket sock = null;
private BufferedReader br = null;
public InputThread(Socket sock, BufferedReader br){
this.sock = sock;
this.br = br;
}
public void run() {
try{
String line = null;
while((line = br.readLine()) != null) {
System.out.println(line);
}
}catch(Exception ex){
}finally{
try{
if(br != null) br.close();
}catch(Exception ex) {}
try{
if(sock != null) sock.close();
}catch(Exception ex) {}
}
}
}
출처 : 김성박 송지훈 공저, 『 자바 IO & NIO 네트워크 프로그래밍』, 한빛미디어(2004.9.30), 8장 인용.