package ex03;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
public class MultiChatServer {
//서버소켓 참조변수 ss선언
private ServerSocket ss = null;
//소켓 참조변수 s 선언
private Socket s = null;
//ChatThread 제네릭 타입의 어레이리스트 참조변수 chatlist+ 객체생성
ArrayList <ChatThread> chatlist = new ArrayList <ChatThread>();
public void start() {
try {
//서버소켓 객체생성 서버포트번호를 매개변수로 받아서 생성과 동시에 소켓 바인딩
ss = new ServerSocket(8888);
System.out.println("server start");
//클라이언트의 연결요청이 올때까지 반복하기 위한 무한루프
while(true) {
//System.out.println("연결요청 기다리는 중 ");
//연결수락 + 통신소캣 생성(소캣 객체생성)
//accept()-> 연결요청이 들어올 떄까지 대기(블로킹상태) 요청이 들어오면 통신용 객체 (Socket)생성
s = ss.accept();
//쓰레드 객체 생성
ChatThread chat = new ChatThread();
//쓰레드 리스트 (chatlist)에 해당 쓰레드 추가
chatlist.add(chat);
//start()호출해서 작업 시작
chat.start();
}
} catch(Exception e) {
System.out.println("[MultiChatServer]start() Exception 발생!!");
}
}
public static void main(String[] args) {
MultiChatServer server = new MultiChatServer();
server.start();
}
void msgSendAll(String msg) { //전부 출력 메소드
for(ChatThread ct : chatlist) {
ct.outMsg.println(msg); //채팅내용을 매개변수로 받아서 쓰레드 리스트에 있는 모든 쓰레드에게 출력
}
}
class ChatThread extends Thread {
String msg;
String[] rmsg;
private BufferedReader inMsg = null;
private PrintWriter outMsg = null;
public void run() {
boolean status = true; //반복작업을 위한 true
System.out.println("##ChatThread start...");
try {
//socket.getInputStream() 통신소켓에 인풋스트림 객체를 얻음
//new InputStreamReader(socket.getInputStream(
//)->생성된 바이트기반 인풋스트림을 문자기반 스트림으로 연결
// 인코딩 매개변수가 없으므로 해당 os에서 사용하는 기본 인코딩 문자로 변환하는 InputStreamReader를 생성
//입출력의 효율을 높이기 위해 보조스트림(BufferedReader)연결
inMsg = new BufferedReader(new InputStreamReader(s.getInputStream()));
//다양한 문자처리가 편한 PrintWriter 객체생성(auto flush값이 true이므로 println메서드 호출 될 때마다 자동으로 flush
outMsg = new PrintWriter(s.getOutputStream(), true);
while(status) {
msg = inMsg.readLine();
rmsg = msg.split("/");
if(rmsg[1].equals("logout")) {
chatlist.remove(this);
msgSendAll("server/" + rmsg[0] + "님이 종료했습니다.");
status = false;
}
else if(rmsg[1].equals("login")) {
msgSendAll("server/"+rmsg[0]+"님이 로그인했습니다.");
}
else {
msgSendAll(msg);
}
}
this.interrupt();
System.out.println("##"+this.getName()+"stop!!");
} catch(IOException e) {
chatlist.remove(this);
// e.printStackTrace();
System.out.println("[ChatThread]run() IOException 발생!!");
}
}
}
}