본문 바로가기

자바

자바(JAVA) 채팅 프로그램(2) (웹 소켓 TCP/IP)

반응형

이전 글에서는 프로그램의 실행 결과와 웹 소켓에 대해서 알아보았다.

이 글에서는 채팅 프로그램의 전반적인 코드를 살펴보겠다.

ChatServer.java

package server;

import java.net.InetAddress;
import java.net.ServerSocket;

import server.thread.AcceptThread;


public class ChatServer {
	
	public ServerSocket server;
	
	public ChatServer() {
		try {
			server = new ServerSocket(8000);
			System.out.println("[ "+InetAddress.getLocalHost()+" ] - 서버 소켓 생성");
		}catch(Exception e) {
			System.out.println("::: 소켓 생성 오류 :::");
			System.exit(0);
		}
		
		new AcceptThread(this).start();
	}

	public static void main(String[] args) {
		new ChatServer();
	}

}

서버 소켓을 생성하고 클라이언트 접속을 받는 스레드 new 시킨다.

AcceptThread.java

package server.thread;

import java.net.ServerSocket;
..생략..

public class AcceptThread extends Thread{
	ChatServer main;
	
	public ArrayList<ClientThread> clients = new ArrayList<ClientThread>();
	public CJDBC db = new CJDBC();
	public Connection con = db.getCon();
	public String sql = "select * from member where m_id = ? and m_pw = ? ";
	public PreparedStatement pstmt;
	
	public AcceptThread(ChatServer main) {
		pstmt = db.getPSTMT(sql);
		this.main = main;
	}
	
	@Override
	public void run() {
		System.out.println("::: 채팅서버 시작 - 접속 대기 :::");
		while(true) {
			String ip="";
			try {
				Socket socket = main.server.accept();
				ip = socket.getRemoteSocketAddress().toString();
				System.out.println("[ 클라이언트 접속 ] - "+socket.getRemoteSocketAddress());
				ClientThread ct = new ClientThread(AcceptThread.this,socket);
				clients.add(ct);
				ct.start();
			} catch (Exception e) {
				System.out.println("[ "+ip+" ] 접속 오류!! ");
			}
		}
	}
}

클라이언트의 접속이 올 때까지 대기한다.

클라이언트는 ip와 포트를 입력하여 서버에 접속한다.

ConnectClass.java

package client;

import java.io.IOException;
..생략..

public class ConnectClass {
	IPForm ipForm;
	String ip;
	String port;
	public Socket socket;
	
	public InputStream in;
	public OutputStream out;
	public ObjectInputStream oin;
	public ObjectOutputStream oout;
	public LoginForm login ;
	
	public ConnectClass(IPForm ipForm) {
		this.ipForm = ipForm;
		
		ip = ipForm.ipF.getText();
		System.out.println("**** ip "+ip);
		port = ipForm.portF.getText();
		System.out.println("**** port "+port);
		int port =Integer.parseUnsignedInt(ipForm.portF.getText());
		try {
			socket = new Socket(ip,port);
			in = socket.getInputStream();
			out = socket.getOutputStream();
			oout = new ObjectOutputStream(out);
			oin = new ObjectInputStream(in);
		} catch (Exception e1) {
			System.exit(0);
		} 
		
		ipForm.setVisible(false);
		
		login = new LoginForm(this);
		new RecvThread(this, login).start();

	}

}

클라이언트가 접속하면 클라이언트쓰레드를 생성해 클라이언트와 통신을 시작한다.

ClientThread.java

package server.thread;

import java.io.InputStream;
..생략..

public class ClientThread extends Thread{
	public AcceptThread accept;
	public Socket socket;
	public String name;
	
	public InputStream in;
	public OutputStream out;
	public ObjectInputStream oin;
	public ObjectOutputStream oout;
	
	HashMap<String,Object> response;
	
	public ClientThread(AcceptThread accept, Socket socket) throws Exception{
		this.accept = accept;
		this.socket = socket;
		
		in = socket.getInputStream();
		out = socket.getOutputStream();
		oin = new ObjectInputStream(in);
		oout = new ObjectOutputStream(out);
	}
	
	@Override
	public void run() {
		try {
			while(true) {
				HashMap<String , Object> request = (HashMap<String , Object>)oin.readObject();
				if(request.get("protocol") == null) {
					break;
				}
				int protocol = (int)request.get("protocol");
				System.out.println("클라이언트 요청  - protocol:" + protocol);
				switch(protocol) {
				
				case 1101: 
					response = new LoginClass(this).loginProc(request);
					new SendHash(this,response).send();
					break;
				
				case 1201:
					response = new ChatClass(this).chatProc(request);
					synchronized(accept.clients){
						for(int i =0;i<accept.clients.size();i++) {
							new SendHash(accept.clients.get(i),response).send();
						}
					}
					break;
				case 1301:
					response = new UploadClass(this).uploadProc(request);
					new SendHash(this,response).send();
					break;
				
				case 1302:
					response = new ListClass(this).listProc(request);
					new SendHash(this,response).send();
					break;
			
				case 1303:
					response = new DownloadClass(this).downloadProc(request);
					new SendHash(this,response).send();
					break;
				}
			}
		} catch (Exception e) {
			System.out.println(socket.getRemoteSocketAddress()+"클라이언트 종료");
			try {
				in.close();
				out.close();
				oin.close();
				oout.close();
				socket.close();
			} catch (Exception e1) {}
			synchronized(accept.clients) {
				accept.clients.remove(this);
			}
		}
	}


}

클라이언트의 요청에 맞게 처리해주면 된다.

채팅 프로그램의 구성

 

인터넷에 채팅프로그램 예제는 워낙 많으니 한 번쯤 해보며 웹소켓에 대해 연습해보는 것도 나쁘지 않은 것 같다.

ChatProgram.zip
0.23MB

반응형