본문 바로가기

JAVA

JAVA 소켓 채팅 프로그램 (server)

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 발생!!");
			}
		}
	}
	
}