ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 간단한 채팅 (Socket)
    개발 2021. 9. 5. 03:02
    728x90

    대충 원리

    그림으로 그리면 이렇고

    클라이언트가 서버한테 메세지를보내면

    서버가 그냥 모든클라이언트에게 메세지송신하고

    클라이언트가 그 메세지를 수신함

    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
Designed by Tistory.