반응형
# Java Socket(소켓)을 이용한 Multi-Chatting 프로그래밍
- 멀티 채팅 구현 작업 진행.
- 서버에서 HashMap 이용하여 멀티 채팅 구현.
- 연결, 접속에 따른 알림 표시.
- 서버 : 서버에서는 HashMap 이용하여 클라이언트 관련 정보 담고, Thread를 이용하여 HashMap에 저장된 클라이언트 정보를 바탕으로 브로드 캐스팅 진행.
- 클라이언트 : 보내는 쪽은 sender 라는 Thread 에 소켓 정보와 클라이언트 정보를 서버에 보내서 작업. 받는 쪽은 receiver 라는 Thread 에 소켓 정보를 담아 데이터 수신.
## 작업 소스
Project06F_MultiChatServer
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
public class Project06F_MultiChatServer {
HashMap clients;
Project06F_MultiChatServer() {
clients = new HashMap();
Collections.synchronizedMap(clients); // 동기화를 위해 사용.
}
public void start() {
ServerSocket serverSocket = null;
Socket socket = null;
try {
serverSocket = new ServerSocket(9999);
System.out.println("서버 실행...");
while (true) {
socket = serverSocket.accept(); // 클라이언트의 정보를 알고 있는 소켓.
System.out.println(socket.getInetAddress() + ":" + socket.getPort() + " 연결.");
ServerReceiver thread = new ServerReceiver(socket);
thread.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 브로드캐스팅 기능
void sendToAll(String msg) {
Iterator iterator = clients.keySet().iterator();
while (iterator.hasNext()) {
try {
DataOutputStream out = (DataOutputStream) clients.get(iterator.next());
out.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] agrg) {
new Project06F_MultiChatServer().start();
}
// inner class (클래스 내부에 있는 클래스를 의미)
public class ServerReceiver extends Thread {
Socket socket;
DataInputStream in;
DataOutputStream out;
ServerReceiver(Socket socket) {
this.socket = socket;
try {
in = new DataInputStream(socket.getInputStream());
out = new DataOutputStream(socket.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
String name = "";
try {
name = in.readUTF();
// HashMap 에 사용자 이름 존재유무 체크.
if (clients.get(name) != null) {
out.writeUTF("이미 존재하는 이름입니다 : " + name);
out.writeUTF("다른 이름으로 다시 연결해주세요.");
System.out.println(socket.getInetAddress() + ":" + socket.getPort() + " 연결 종료.");
in.close();
out.close();
socket.close();
socket = null;
} else {
sendToAll("#" + name + " 님께서 입장하셨습니다.");
clients.put(name, out);
while (in != null) {
sendToAll(in.readUTF());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (socket != null) {
sendToAll("#" + name + " 님께서 접속을 종료하였습니다.");
clients.remove(name);
System.out.println(socket.getInetAddress() + ":" + socket.getPort() + " 연결 종료.");
}
}
}
}
}
Project06F_MultiChatClient
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Project06F_MultiChatClient {
public static void main(String[] args) {
try {
Socket socket = new Socket("127.0.0.1", 9999);
Scanner scanner = new Scanner(System.in);
System.out.println("name : ");
String name = scanner.nextLine();
Thread sender = new Thread(new ClientSender(socket, name));
Thread receiver = new Thread(new ClientReceiver(socket));
sender.start();
receiver.start();
} catch (Exception e) {
e.printStackTrace();
}
}
// inner class
static class ClientSender extends Thread {
Socket socket;
DataOutputStream out;
String name;
ClientSender(Socket socket, String name) {
this.socket = socket;
this.name = name;
try {
out = new DataOutputStream(socket.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
Scanner scanner = new Scanner(System.in);
try {
if (out != null) {
out.writeUTF(name);
}
while (out != null) {
String message = scanner.nextLine();
if (message.equals("quit")) {
break;
}
out.writeUTF("[" + name + "] : " + message);
}
out.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
static class ClientReceiver extends Thread {
Socket socket;
DataInputStream in;
ClientReceiver(Socket socket) {
this.socket = socket;
try {
in = new DataInputStream(socket.getInputStream());
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() {
while (in != null) {
try {
System.out.println(in.readUTF());
} catch (Exception e) {
e.printStackTrace();
break;
}
}
try {
in.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
## 실행방법
서버 실행
- 관리자 권한으로 cmd 실행
- 워크스페이스의 bin 폴더까지 들어간 후 java Project06F_MultiChatServer 입력하여 서버 실행.
클라이언트 실행
- 관리자 권한으로 cmd 실행
- 워크스페이스의 bin 폴더까지 들어간 후 java Project06F_MultiChatClient 입력하여 서버 실행. (멀티 채팅이므로 cmd 하나 더 실행해서 동일하게 실행)
반응형
'인프런 강의 학습 > Java TPC 실전' 카테고리의 다른 글
Java Socket(소켓) Multi-Chatting 프로그래밍_소켓이 만들어지는 과정(TCP 3-way Handshake), 자바에서 소켓 만들기 (ECHO) (0) | 2022.08.03 |
---|---|
Java MQTT Client 만들기_Java 에서 MQTT 연동하기. (0) | 2022.08.02 |
Java MQTT Client 만들기_Mosquitto MQTT broker 설치 및 서버구동 (0) | 2022.07.29 |
Java iText API 활용 Excel에서 데이터 읽어서 PDF로 만들기 (0) | 2022.07.28 |
Java iText API 활용 PDF 에 image 삽입 및 크기조절 하기 (0) | 2022.07.27 |