[채팅 프로그램] Socket 활용한 간단한 콘솔 채팅 프로그램

권용환·2021년 11월 4일
0

프로젝트

목록 보기
1/1

Project

Description

  • 콘솔 채팅 구현 (서버와 클라이언트)
  • 종료되지 않으면 답이 올때까지 무한 대기
    • 이는 추후 GUI를 활용한 채팅 프로그램 만들어 볼 예정
  • "종료" 라는 단어가 들어간 문장 전송 시 서버-클라이언트 간의 대화 연결 종료
  • socket 활용

고찰

  • 무한 대기가 필요하다
    • GUI를 활용하면 이 문제를 해결 가능하다
    • 추후 만들어 볼 예정
  • 쓰레드를 활용하지 않아서 특정 사람과의 1대1 통신만 가능하다
    • 추후 멀티쓰레드를 활용한 프로그램 만들어 볼 예정
  • 영어를 사용할 경우
    • inMsg.contains("종료") 대신 inMsg.equalsIgnoreCase("bye") 사용
  • 추가적으로 utf-8 인코딩을 해줄 수도 있을 것으로 보임

Server

Description

  • Serversocket은 특정 포트 번호를 열어두고 대기
  • 연결 요청이 오면 accept하고 내부에 별도의 Socket 생성
  • BufferedReader와 BufferedWriter를 활용해 Stream을 연결하고 클라이언트의 대화가 도착할 때까지 무한 대기
  • 메세지가 들어오면 String으로 받은 뒤, "종료"가 포함되어 있는지 확인
  • 포함되어 있지 않다면 클라이언트 메세지를 print
  • 이후 내가 메세지를 입력하고, Buffer를 이용하므로 반드시 flush() 해주기
  • 다시 메세지가 도착할 때까지 무한 대기
  • 이후, 종료가 도착하게 되면 finally 구문으로 가서 사용한 리소스 해제
  • 중간에 예외 발생해도 catch하고 리소스는 해제

전체 코드

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {

    public static void main(String[] args) {

        ServerSocket serverSocket = null;
        Socket socket = null;
        BufferedReader in = null;
        BufferedWriter out = null;
        Scanner sc = new Scanner(System.in);

        try {
            serverSocket = new ServerSocket(12000);
            System.out.println("연결 대기 중입니다");

            socket = serverSocket.accept();
            System.out.println("연결이 완료되었습니다");

            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            while (true) {
                String inMsg = in.readLine();
                if (inMsg.contains("종료")) {
                    System.out.println("상대방 : " + inMsg);
                    System.out.println("연결이 종료되었습니다");
                    break;
                }

                System.out.println("상대방 : " + inMsg);
                System.out.print("메시지를 입력하세요 : ");

                String outMsg = sc.nextLine();
                out.write(outMsg + "\n");
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                sc.close();
                out.close();
                in.close();
                socket.close();
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Client

Description

  • Host ip와 port 번호를 가진 Socket 생성
  • BufferedReader와 BufferedWriter를 활용해 Stream을 연결하고 클라이언트의 대화가 도착할 때까지 무한 대기
  • 먼저 메시지 입력하고 이 메세지에 "종료"가 포함되어 있으면 메세지를 보낸 후 연결 종료
  • 포함되어 있지 않다면 전송 후 상대방의 메세지가 올 때까지 무한 대기
  • 이후, 종료가 도착하게 되면 finally 구문으로 가서 사용한 리소스 해제
  • 중간에 예외 발생해도 catch하고 리소스는 해제

전체 코드

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;

public class Client {

    public static void main(String[] args) {

        Socket socket = null;
        BufferedReader in = null;
        BufferedWriter out = null;
        Scanner sc = new Scanner(System.in);

        try {
            socket = new Socket("localhost", 12000);

            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));

            while (true) {
                System.out.print("메시지를 입력하세요 : ");
                String outMsg = sc.nextLine();

                if (outMsg.contains("종료")) {
                    out.write("연결이 종료되었습니다");
                    out.flush();
                    System.out.println("연결이 종료되었습니다");
                    break;
                }

                out.write(outMsg + "\n");
                out.flush();

                String inMsg = in.readLine();
                System.out.println("상대방 : " + inMsg);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                sc.close();
                out.close();
                in.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

실행

  1. Server를 실행합니다

  2. Client를 실행합니다

  3. Client가 실행되면 Server는 연결이 수락되고 내부 소켓이 생성됩니다

  4. Client가 반갑게 인사합니다

  5. Client의 메세지가 서버의 화면에 출력됩니다

  6. Server가 답장을 보냅니다

  7. Server의 메세지가 클라이언트의 화면에 출력됩니다

  8. Client가 연결 종료를 요청하며 내부 리소스가 반환됩니다

  9. Server도 연결이 종료되고 내부 리소스가 반환됩니다

참고

김기태의 Java를 자바

profile
마구 낙서하는 블로그입니다

0개의 댓글