본문 바로가기
Web & Mobile/JAVA

Lecture 36 - Java(15) 채팅프로그램

by Bennyziio 2023. 6. 20.
반응형

SearchZipcodeEx01.SearchZipcodeServerEx01

package SearchZipcodeEx01;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SearchZipcodeServerEx01 {

	public static void main(String[] args) {
		ServerSocket serverSocket = null;
		Socket socket = null;

		BufferedWriter bw = null;
		BufferedReader br = null;
		
		Connection conn = null;
		Statement stmt = null;
		
		ResultSet rs = null;
		
		try {
			serverSocket = new ServerSocket(7777);		// 개방될 포트 : 7777
			
			while(true) {
				try {
					System.out.println("서버가 준비되었습니다.");
					socket = serverSocket.accept();				// 클라이언트 대기
					System.out.println("클라이언트에 연결되었습니다" + socket.getInetAddress());
					br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
					bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
					
					String dongname = br.readLine();
					//System.out.println(dongname + "\n");
					String url = "jdbc:oracle:thin:@localhost:1521:orcl";
					String user = "scott";
					String password = "tiger";
					
					Class.forName("oracle.jdbc.driver.OracleDriver");
					System.out.println("드라이버 로딩 성공");
					
					conn = DriverManager.getConnection(url, user, password);
					System.out.println("연결 성공");
					
					stmt = conn.createStatement();
					
					String sql = String.format("select zipcode, sido, gugun, dong, ri, bunji from zipcode where dong like '%s'", "%" + dongname +"%");
					rs = stmt.executeQuery(sql);
					
					while(rs.next()) {
						String line = String.format("[%s]\t%s\t%s\t%s\t%s\t%s\n",
								rs.getString("zipcode"),
								rs.getString("sido"),
								rs.getString("gugun"),
								rs.getString("dong"),
								rs.getString("ri"),
								rs.getString("bunji")
								);
						bw.write(line + "\n");
						bw.flush();
						/*
						System.out.printf("[%s]\t%s\t%s\t%s\t%s\t%s\n",
								rs.getString("zipcode"),
								rs.getString("sido"),
								rs.getString("gugun"),
								rs.getString("dong"),
								rs.getString("ri"),
								rs.getString("bunji")
								);
								*/
					};
					
				} catch (NumberFormatException e) {
					e.printStackTrace();
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} catch (SQLException e) {
					e.printStackTrace();
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				} finally {
					if(bw != null) try {bw.close();} catch(IOException e) {};
					if(br != null) try {br.close();} catch(IOException e) {};
					if(socket != null) try {socket.close();} catch(IOException e) {};
					if(conn != null) try {conn.close();} catch(SQLException e) {};
					if(stmt != null) try {stmt.close();} catch(SQLException e) {};
					if(rs != null) try {rs.close();} catch(SQLException e) {};
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(serverSocket != null) try {serverSocket.close();} catch(IOException e) {};
		}
	}
}

SearchZipcodeEx01.SearchZipcodeClientEx01

package SearchZipcodeEx01;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;

public class SearchZipcodeClientEx01 {

	public static void main(String[] args) {

		Socket socket = null;
		
		BufferedWriter bw = null;
		BufferedReader br = null;
		
		while(true) {
			try {
				br = new BufferedReader(new InputStreamReader(System.in));
				System.out.print("동이름 > ");
				String dongname = br.readLine();
				
				System.out.println("서버와 연결 중입니다");
				socket = new Socket("localhost", 7777);
				System.out.println("서버와 연결 되었습니다");
				
				bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "utf-8"));
				br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));
				
				/*
				bw.write(dongname + "\n");
				bw.flush();
				System.out.println("전송이 완료되었습니다.");
				
				String msg = null;
				while((msg = br.readLine()) != null) {
					System.out.println(msg);
				}
				*/
				
				if(dongname.length() <=1) {
					System.out.println("동이름을 2자 이상으로 입력하세요");
					continue;
				}
				if (dongname.charAt(0)<0xAC00 || dongname.charAt(0)>0xD7A3) {
		        	System.out.println("동이름의 첫자를 한글로 입력해 주시기 바랍니다");
		        	continue;
		        }
				bw.write(dongname + "\n");
				bw.flush();
				System.out.println("전송이 완료되었습니다.");
				
				String msg = null;
				while((msg = br.readLine()) != null) {
					System.out.println(msg);
				}
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if(bw != null) try {bw.close();} catch(IOException e) {};
				if(br != null) try {br.close();} catch(IOException e) {};
				if(socket != null) try {socket.close();} catch(IOException e) {};
			}
		}
	}
}

Chatting program

chat.ChatServer

package chat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;

public class ChatServer {
	private HashMap<String, OutputStream> clients;
	
	public static void main(String[] args) {
		
		new ChatServer().start();
		
	}
	
	public ChatServer() {
		clients = new HashMap<String, OutputStream>();
	}
	
	public void start() {
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		try {
			serverSocket = new ServerSocket(7777);
			System.out.println("서버가 시작되었습니다");
			
			while(true) {
				socket = serverSocket.accept();
				System.out.println("[" + socket.getInetAddress() + " : " + socket.getPort() + "]" + "에서 접속하였습니다.");
				ServerReceiver thread = new ServerReceiver(socket);
				thread.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void sendToAll(String msg) {
		Iterator<String> it = clients.keySet().iterator();
		
		while(it.hasNext()) {
			try {
				DataOutputStream out = (DataOutputStream)clients.get(it.next());
				out.writeUTF(msg);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public class ServerReceiver extends Thread {
		private Socket socket;
		private DataInputStream in;
		private DataOutputStream out;
		
		public ServerReceiver(Socket socket) {
			this.socket = socket;
			
			try {
				in = new DataInputStream(socket.getInputStream());
				out = new DataOutputStream(socket.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			String name = "";
			try {
				name = in.readUTF();
				sendToAll("#" + name + "님이 들어오셨습니다.");
				
				clients.put(name,out);
				
				System.out.println("현재 서버접속자 수는 " + clients.size() + "입니다.");
				
				while(in != null) {
					sendToAll(in.readUTF());
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				sendToAll("#" + name + "님이 나가셨습니다.");
				clients.remove(name);
				System.out.println("[" + socket.getInetAddress() + ":" + socket.getPort() + "]" + " 에서 접속을 종료하였습니다.");;
				System.out.println("현재 서버접속자 수는 " + clients.size() + " 입니다.");
			}
		}
	}
}

chat.ChatClient

package chat;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ChatClient {

	public static void main(String[] args) {
		if(args.length != 1) {
			System.out.println("USAGE : java ChatClient 대화명");
			System.exit(0);
		}
		
		try {
			Socket socket = new Socket("localhost", 7777);
			System.out.println("서버에 연결되었습니다.");
			
			Thread sender = new Thread(new ClientSender(socket, args[0]));
			Thread receiver = new Thread(new ClientReceiver(socket));
			
			sender.start();
			receiver.start();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	static class ClientSender extends Thread {
		private Socket socket;
		private DataOutputStream out;
		private String name;
		
		public ClientSender(Socket socket, String name) {
			this.socket = socket;
			try {
				out = new DataOutputStream(socket.getOutputStream());
				this.name = name;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	
		public void run() {
			BufferedReader br = null;
			try {
				br = new BufferedReader(new InputStreamReader(System.in));
				if(out != null) {
					out.writeUTF(name);
				}
				
				while(out != null) {
					out.writeUTF("[" + name + "]" + br.readLine());
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if(br != null) try {br.close();} catch(IOException e) {};
			}
		}
	}
	
	static class ClientReceiver extends Thread {
		private Socket socket;
		private DataInputStream in;
		
		public ClientReceiver(Socket socket) {
			this.socket = socket;
			
			try {
				in = new DataInputStream(socket.getInputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run() {
			while(in != null) {
				try {
					System.out.println(in.readUTF());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

chat.ChatServer - 나가기 명령받으면 나가기

package chat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;

public class ChatServer {
	private HashMap<String, OutputStream> clients;
	
	public static void main(String[] args) {
		
		new ChatServer().start();
		
	}
	
	public ChatServer() {
		clients = new HashMap<String, OutputStream>();
	}
	
	public void start() {
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		try {
			serverSocket = new ServerSocket(7777);
			System.out.println("서버가 시작되었습니다");
			
			while(true) {
				socket = serverSocket.accept();
				System.out.println("[" + socket.getInetAddress() + " : " + socket.getPort() + "]" + "에서 접속하였습니다.");
				ServerReceiver thread = new ServerReceiver(socket);
				thread.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void sendToAll(String msg) {
		Iterator<String> it = clients.keySet().iterator();
		
		while(it.hasNext()) {
			try {
				DataOutputStream out = (DataOutputStream)clients.get(it.next());
				out.writeUTF(msg);

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public class ServerReceiver extends Thread {
		private Socket socket;
		private DataInputStream in;
		private DataOutputStream out;
		
		public ServerReceiver(Socket socket) {
			this.socket = socket;
			
			try {
				in = new DataInputStream(socket.getInputStream());
				out = new DataOutputStream(socket.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			String name = "";
			try {
				// 아이디
				name = in.readUTF();
				// sendToAll() : 전체 방송할 내용
				sendToAll("#" + name + "님이 들어오셨습니다.");
				// Hashmap : 사용자의 아이디, outputstream -> thread -> client
				clients.put(name,out);
				
				System.out.println("현재 서버접속자 수는 " + clients.size() + "입니다.");

				/*
				while(in != null) {
					sendToAll(in.readUTF());
				}
				 */
				while(in != null) {
					String msg = in.readUTF();
					if(msg.endsWith("나가기"))
						break;
					// msg가 들어오면 쏴줘라
					sendToAll(msg);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				sendToAll("#" + name + "님이 나가셨습니다.");
				clients.remove(name);
				System.out.println("[" + socket.getInetAddress() + ":" + socket.getPort() + "]" + " 에서 접속을 종료하였습니다.");;
				System.out.println("현재 서버접속자 수는 " + clients.size() + " 입니다.");
			}
		}
	}
}

chat.ChatClient - 나가기 명령 입력하면 나가기

package chat;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ChatClient {

	public static void main(String[] args) {
		if(args.length != 1) {
			System.out.println("USAGE : java ChatClient 대화명");
			System.exit(0);
		}
		
		try {
			Socket socket = new Socket("localhost", 7777);
			System.out.println("서버에 연결되었습니다.");
			
			Thread sender = new Thread(new ClientSender(socket, args[0]));
			Thread receiver = new Thread(new ClientReceiver(socket));
			
			sender.start();
			receiver.start();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	static class ClientSender extends Thread {
		private Socket socket;
		private DataOutputStream out;
		private String name;
		
		public ClientSender(Socket socket, String name) {
			this.socket = socket;
			try {
				out = new DataOutputStream(socket.getOutputStream());
				this.name = name;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	
		public void run() {
			BufferedReader br = null;
			try {
				br = new BufferedReader(new InputStreamReader(System.in));
				if(out != null) {
					out.writeUTF(name);
				}
				/*
				while(out != null) {
					out.writeUTF("[" + name + "]" + br.readLine());
				}
				 */
				while(out != null) {
					String msg = br.readLine();
					out.writeUTF("[" + name + "]" + msg);
					if(msg.equals("나가기")) {
						System.exit(0);
					}
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if(br != null) try {br.close();} catch(IOException e) {};
			}
		}
	}
	
	static class ClientReceiver extends Thread {
		private Socket socket;
		private DataInputStream in;
		
		public ClientReceiver(Socket socket) {
			this.socket = socket;
			
			try {
				in = new DataInputStream(socket.getInputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run() {
			while(in != null) {
				try {
					System.out.println(in.readUTF());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

귓속말 기능
chat.chatServer

package chat;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;

public class ChatServer {
	private HashMap<String, OutputStream> clients;
	
	public static void main(String[] args) {
		
		new ChatServer().start();
		
	}
	
	public ChatServer() {
		clients = new HashMap<String, OutputStream>();
	}
	
	public void start() {
		ServerSocket serverSocket = null;
		Socket socket = null;
		
		try {
			serverSocket = new ServerSocket(7777);
			System.out.println("서버가 시작되었습니다");
			
			while(true) {
				socket = serverSocket.accept();
				System.out.println("[" + socket.getInetAddress() + " : " + socket.getPort() + "]" + "에서 접속하였습니다.");
				ServerReceiver thread = new ServerReceiver(socket);
				thread.start();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void sendToAll(String msg) {
		Iterator<String> it = clients.keySet().iterator();
		
		while(it.hasNext()) {
			try {
				DataOutputStream out = (DataOutputStream)clients.get(it.next());
				out.writeUTF(msg);

			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public void whisper(String name, String msg) {
		try {
			DataOutputStream out = (DataOutputStream)clients.get(name);
			out.writeUTF(msg);

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public class ServerReceiver extends Thread {
		private Socket socket;
		private DataInputStream in;
		private DataOutputStream out;
		
		public ServerReceiver(Socket socket) {
			this.socket = socket;
			
			try {
				in = new DataInputStream(socket.getInputStream());
				out = new DataOutputStream(socket.getOutputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void run() {
			String name = "";
			try {
				// 아이디
				name = in.readUTF();
				// sendToAll() : 전체 방송할 내용
				sendToAll("#" + name + "님이 들어오셨습니다.");
				// Hashmap : 사용자의 아이디, outputstream -> thread -> client
				clients.put(name,out);
				
				System.out.println("현재 서버접속자 수는 " + clients.size() + "입니다.");

				/*
				while(in != null) {
					sendToAll(in.readUTF());
				}
				 */
				while(in != null) {
					String msg = in.readUTF();
					if(msg.endsWith("나가기")) {
						break;
					}
					
					if(msg.contains("#")) {
						String[] splits = msg.split("#");
						whisper(splits[1], splits[0] + "의 귓속말 : " + splits[2]);
					}
					else {
						sendToAll(msg);
					}
					
				}
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				sendToAll("#" + name + "님이 나가셨습니다.");
				clients.remove(name);
				System.out.println("[" + socket.getInetAddress() + ":" + socket.getPort() + "]" + " 에서 접속을 종료하였습니다.");;
				System.out.println("현재 서버접속자 수는 " + clients.size() + " 입니다.");
			}
		}
	}
}

chat.chatClient

package chat;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;

public class ChatClient {

	public static void main(String[] args) {
		if(args.length != 1) {
			System.out.println("USAGE : java ChatClient 대화명");
			System.exit(0);
		}
		
		try {
			Socket socket = new Socket("localhost", 7777);
			System.out.println("서버에 연결되었습니다.");
			
			Thread sender = new Thread(new ClientSender(socket, args[0]));
			Thread receiver = new Thread(new ClientReceiver(socket));
			
			sender.start();
			receiver.start();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	static class ClientSender extends Thread {
		private Socket socket;
		private DataOutputStream out;
		private String name;
		
		public ClientSender(Socket socket, String name) {
			this.socket = socket;
			try {
				out = new DataOutputStream(socket.getOutputStream());
				this.name = name;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run() {
			BufferedReader br = null;
			
			try {
				br = new BufferedReader(new InputStreamReader(System.in));
				if(out != null) {
					out.writeUTF(name);
				}
				/*
				while(out != null) {
					out.writeUTF("[" + name + "]" + br.readLine());
				}
				 */
				while(out != null) {
					
					String msg = br.readLine();
					out.writeUTF("[" + name + "]" + msg);
					if(msg.equals("나가기")) {
						System.exit(0);
					}
				}
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if(br != null) try {br.close();} catch(IOException e) {};
			}
		}
	}
	
	static class ClientReceiver extends Thread {
		private Socket socket;
		private DataInputStream in;
		
		public ClientReceiver(Socket socket) {
			this.socket = socket;
			
			try {
				in = new DataInputStream(socket.getInputStream());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		public void run() {
			while(in != null) {
				try {
					System.out.println(in.readUTF());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

public void whisper(String name, String msg) { try { DataOutputStream out = (DataOutputStream)clients.get(name); out.writeUTF(msg); } catch (IOException e) { e.printStackTrace(); } }

우리는 클라이언트가 보내는 정보를 id와 메세지로 같이 받아올 것이고 이를 구분하기 위해 #을 이용할 것이다. 나의 id 상대방 id 메세지 총 3개의 배열에 저장하고 이를 이용하여 상대방 id를 지정하여 메세지를 송부할 것이다.
whisper가 (String name, String msg)라고하여 두개의 값을 받아 오는 함수를 만들고
여기에서 DatOutputStream out = (DataOutputStream)clients.get(name)으로 clients의 입장에서 내보넬 id(상대방이 됨)를 get(name)으로 상대방 id로 지정해 주고
out.writeUTF(msg)로 지정된 상대방에게 msg를 보내는 명령어를 작성한다

while(in != null) {
					String msg = in.readUTF();
					if(msg.endsWith("나가기")) {
						break;
					}
					
					if(msg.contains("#")) {
						String[] splits = msg.split("#");
						whisper(splits[1], splits[0] + "의 귓속말 : " + splits[2]);
					}
					else {
						sendToAll(msg);
					}
				}

두번째 if를 보면 msg.contains("#") 즉 #을 포함한 메세지를 받았을 경우 귓속말 기능을 하는 구문으로 빠지게 한다. 배열을 선언하고 split("#")으로 분리되게 만들어준다
그러면 split[0]은 첫번째 #전까지
split[1]은 첫번째#과 두번째# 사이
split[2]는 두번째#과 세번째# 사이 여기선 마지막 값이 되겠다.
split[0]#split[1]#split[2]가 되는 것이다.
이렇게 받아온 데이터는 쓰레드 안에 있으며 쓰레드에서 다시 지정된 id의 클라이언트에게 반환하게 되는데 이를 만들어둔 whisper함수를 사용하여 (상대방id(splits[1]), 나의 id(splits[0]) + 보낼메시지(splits[2])를 보내주게 된다.
이는 whisper 함수가 (String name, String msg)라는 2개의 방을 만들어 놨는데 딱 2가지의 데이터를 방에 보낼 수 있게 되어 있다.
이렇게 귓속말을 보내고 받을 수 있게 되었다.

반응형

댓글