-
Java 간단한 채팅 (Socket)개발 2021. 9. 5. 03:02728x90
대충 원리
그림으로 그리면 이렇고
클라이언트가 서버한테 메세지를보내면
서버가 그냥 모든클라이언트에게 메세지송신하고
클라이언트가 그 메세지를 수신함
public class Server_Main { public static Vector<SendandReceive> Clients = new Vector<SendandReceive>(); PrintWriter writer; public static void main(String[] args) { try { ServerSocket server = new ServerSocket(8080); System.out.println("Sever Open"); while(true) { try { Socket sock = server.accept(); System.out.println("한명접속 : " + sock.getInetAddress()); SendandReceive SandR = new SendandReceive(sock); SandR.start(); Clients.add(SandR); } catch(Exception e) { System.out.println("접속중 문제가발생하였습니다"); } } } catch(Exception e){ System.out.println("Server Open faile \n"); } } }
Chat Server
Sever_Main.java
ServerSocket server = new ServerSocket(8080); // 8080포트로 클라리언트를 받음 . Server Open //////////////////////////////////////// Socket sock = server.accept(); System.out.println("한명접속 : " + sock.getInetAddress()); //접속이된 클라이언트의 아이피를 출력해줌 SendandReceive SandR = new SendandReceive(sock); //SandandReceive에 클라이언트의 정보가 담긴 sock을 넘겨줌 SandR.start(); // 쓰레드 생성 Thread.run과 start 차이는 run은 쓰레드를 동기적?으로 생성해줌 //예를 들면 사용자가 한명 들어오면 쓰레드를 생성하는데 그 다음 사용자가 들어오면 전 쓰레드가 종료되기전까지는 생성을 안함 Clients.add(SandR); //모든 클라이언트에게 메세지를 보내야하니까 Client list에 sock을 추가해줌
SendandReceive.java
public class SendandReceive extends Thread{ Socket sock; InputStream input; DataOutputStream dous; String msg; public SendandReceive(Socket sock) { this.sock = sock; } public void run() { try { dous = new DataOutputStream(sock.getOutputStream()); input = sock.getInputStream(); DataInputStream dins = new DataInputStream(input); while(true) { msg = dins.readUTF(); System.out.println(msg); send(msg); } } catch (IOException e) { try { String nickname = msg.split(" ")[0].replace(":",""); System.out.println(nickname + "님이 나가셧습니다"); send(nickname + "님이 나가셧습니다"); } catch (IOException e1) { System.out.println("Exit_Exception Processing Error"); } } } public void send(String msg) throws IOException { for(var cl : Server_Main.Clients) { cl.dous.writeUTF(msg); } } }
============================================================================
설명
public class SendandReceive extends Thread{ Thread 상속 Socket sock; DataOutputStream dous; String msg; public SendandReceive(Socket sock) { this.sock = sock; } public void run() { try { dous = new DataOutputStream(sock.getOutputStream()); // DataInputStream dins = new DataInputStream(sock.getInputStream()); while(true) { msg = dins.readUTF(); //메세지가 오면 msg에 담아줌 System.out.println(msg); // 확인을위해 출력도해주고 send(msg); // 모든 클라이언트에게 다시 전송해줌 } } catch (IOException e) { //중간에 클라이언트가 나갔을 때 try { String nickname = msg.split(" ")[0].replace(":","");// 닉네임 : 메세지 이런식으로 보낼거니까 띄어쓰기로 나눠주고 replace로 :를 제거해줌 System.out.println(nickname + "님이 나가셧습니다"); // 확인을위해 출력해주고 send(nickname + "님이 나가셧습니다"); // 그대로 모든클라이언트에게 전송해줌 } catch (IOException e1) { System.out.println("Exit_Exception Processing Error"); } } } public void send(String msg) throws IOException { for(var cl : Server_Main.Clients) { //리스트에 담긴 클라이언트들을 cl에담고 cl.dous.writeUTF(msg); //인자로 메세지를 받았으니까 그대로 모든 클라이언트에게 전송함 } } }
============================================================================
Chat Client
Client_Main.java
public class Client_Main { public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException { Socket sock = new Socket("127.0.0.1",8080); Scanner scan = new Scanner(System.in); DataOutputStream dous = new DataOutputStream(sock.getOutputStream()); Receive recv = new Receive(sock); recv.start(); System.out.println("닉네임을입력하세요"); String nickName = scan.next(); while(true) { System.out.println("메세지를 입력하세요 :\n"); String msg = scan.nextLine(); dous.writeUTF(nickName+": "+msg); } } }
설명
package Client; import java.io.DataOutputStream; import java.io.IOException; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; public class Client_Main { public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException { Socket sock = new Socket("127.0.0.1",8080);// 127.0.0.1 ,8080포트로 연결 Scanner scan = new Scanner(System.in); // 콘솔 입력받기위한 Scanner객체 생성 DataOutputStream dous = new DataOutputStream(sock.getOutputStream()); // 서버에 메세지를 보내게 도와주는 객체생성 Receive recv = new Receive(sock); //receive에 sock을 넘겨줌 메세지를 수신할거임 recv.start(); // 쓰레드 생성 System.out.println("닉네임을입력하세요"); String nickName = scan.next();// 닉네임입력받고 while(true) { System.out.println("메세지를 입력하세요 :\n"); String msg = scan.nextLine(); // 메세지를 입력받아서 dous.writeUTF(nickName+": "+msg); // nickname: 메세지로 서버로 보내줌 } } }
Recevie.Java
public class Receive extends Thread{ Socket sock; InputStream input; public Receive(Socket sock) { this.sock = sock; } public void run() { try { input = sock.getInputStream(); DataInputStream dins = new DataInputStream(input); while(true) { String line = dins.readUTF(); System.out.println(line); } } catch (IOException e) { System.out.println("메세지를 받는 도중에 에러가 발생했습니다"); e.printStackTrace(); } }
설명
public class Receive extends Thread{ Socket sock; InputStream input; public Receive(Socket sock) { this.sock = sock; } public void run() { try { //👇 메세지를 수신하기위해 datainputstream 객체 생성 DataInputStream dins = new DataInputStream(sock.getInputStream()); while(true) { String line = dins.readUTF(); // 메세지가 오면 System.out.println(line); // 출력을해줌 } } catch (IOException e) { System.out.println("메세지를 받는 도중에 에러가 발생했습니다"); e.printStackTrace(); } }
파이썬으로 프로그래밍 처음 시작하고 기초문법 떼고 나서
만든 게 채팅 프로그램이었는데 자바로 다시 만들어보니까 새로움 ]
실행해보면
사용자가 접속할 때마다 정상적으로 출력해줌
전송하면 다른클라이언트에서도 메시지가 띄워지고
나갔을 때도 정상적으로 출력이 되네요
나갔을 때도 정상적으로 처리가 됨
콘솔이 구려서 나중에 JavaFX로 GUI까지 다시 만들 거 같네요
728x90'개발' 카테고리의 다른 글
재귀함수 (Factorial) (0) 2021.11.30 Typescript 설치 , 쓰는이유 (0) 2021.10.02 Java static을 썼을 때의 차이 (0) 2021.08.28 Nodejs mariaDB(로그인,회원가입 구현) (0) 2021.07.17 pyqt5(2) Thread (0) 2021.07.11