자바로 채팅프로그램 만들기 ( TCP/IP 소켓 + 자바스윙 + 오라클DB )

2019. 6. 27. 10:36개발공부/자바

자바로 채팅 프로그램 만들기

블로그에 올릴 내용이 무엇이 있나 이클립스 폴더를 뒤져보다가 자바로 채팅 프로그램을 짰던 내용이 있어서 올려봅니다. 이전에 파이썬으로 Remote Shell 공격을 공부하면서 소켓에 대해서 학습한 적이 있어서 비교적 쉽게 만들어 볼 수 있었던 걸로 기억합니다.

(보안 공부를 할 때는 주로 파이썬이나 가끔 C언어를 사용했는데 이 프로그램을 짜 보면서부터 자바언어를 주로 사용하게 된 것 같음...)

 

 

실행 화면

 

TCP/IP 소켓의 이해

프로그램으로 채팅 프로그램을 짠다면 자신이 실행 중인 프로그램(프로세스)에서 다른 프로그램(원격지)에게 데이터를 전송할 수 있어야 합니다. 그러기 위해서는 TCP/IP 통신방식의 이해가 필요합니다.

 

먼저 소켓의 흐름을 보기전에 TCP가 무엇인지에 대한 이해가 필요합니다.

TCP와 UDP의 대표적인 차이점은

TCP는 연결지향의 프로토콜이고, UDP는 비연결 지향의 프로토콜이라는 겁니다.

( 채팅 프로그램은 채팅 서버 내의 접속자들이 원활한 채팅을 진행할 수 있도록 데이터 손실이 적은 TCP방식을 사용했습니다. )

 

TCP 프로토콜 흐름도

TCP 방식의 흐름 이해

1. 서버가 Listen상태로 클라이언트의 접속을 기다림

2. 클라이언트가 서버로 SYN (연결 요청)을 보냄

3. 서버는 클라이언트의 요청에 대한 응답을 ( SYN+ACK )를 응답해줌

4. 클라이언트는 서버에 요청 수락 응답에 응답해줌(ACK)   <-- 이때부터 서버와 클라이언트는 연결 상태가 됨

 

 

위에 TCP방식을 이해했다면 소켓으로 채팅프로그램을 짜기 편해집니다.

소켓도 TCP방식과 UDP 방식의 구현이 모두 가능하지만 이글에서는 TCP에 대한 내용만 다루겠습니다.

 

TCP/IP 방식 소켓 흐름도

서버소켓의 입장

1. 먼저 서버가 될 소켓을 생성합니다. - socket()

2. 소켓에 IP주소와 PORT를 바인딩합니다. - bind()

3. 클라이언트의 접속을 기다립니다. - listen()

4. 클라이언트의 요청이 들어오면 요청을 수락합니다. - accept()

5. 클라이언트와 연결이 완료되었다면 데이터를 주고받을 수 있게 됩니다. - send(), recv()

6. 클라이언트가 종료했다면 해당 클라이언트와의 연결을 종료합니다. - close()

 

클라이언트소켓의 입장

1. 클라이언트가 사용할 자신의 소켓을 만듭니다. - socket()

2. 연결할 서버의 주소( IP:PORT ) 로 연결을 요청합니다. - connect()

3. 연결이 성공하면 데이터를 주고받을 수 있게 됩니다. - send(), recv()

4. 종로하고 싶하면 종료하면서 서버에게 종료 알립을 줍니다. - close()

 

 

 

자바로 소켓 프로그래밍

서버의 입장과 클라이언트입장에서 소켓프로그램의 주요부분만 추려서 올렸습니다. 혹시 필요하신분이 있으시다면 하단에 전체코드를 올려두었습니다. 

 

DB에 아이디를 조회하기 위해서 ojdbc6 라이브러리를 사용한 DB 접속 클래스 부분

 

 

서버의 입장

서버소켓 생성

자바에서는 서버소켓을 만들려면 new ServerSocket(사용할 포트주소); 를 사용하면 됩니다. (1번, 2번에 해당)

소켓을 만들었다면 AcceptThread라는 쓰레드를 start 시킵니다. 계속해서 클라이언트들의 요청들을 처리하면서 동시에 접속하는 사용자들을 받기 위해서 쓰레드로 처리하였습니다. ( 쓰레드에대한 설명은 나중에 따로 올리겠습니다. )

 

클라이언트의 요청을 받는 쓰레드

서버 소켓을 만들고 클라이언트의 접속 요청을 받을 준비를 하는부분 입니다.

먼저 오라클 statement를 받아오고 클라이언트 접속요청을 받을 쓰레드를 구현해두었습니다. 

자바에서는 listen과 accept를  sccept()함수 하나로 처리합니다. ( 3번, 4번에 해당 )

accept 과정에서 접속한 클라이언트의 정보를 담고있는 Socket이 반환됩니다.

해당 Socket을 ArrayList에 저장하고 클라이언와의 작업을 처리할 쓰레드를 실행시킵니다.

 

클라이언트 요청처리하는 쓰레드 클래스의 생성자 부분

위에 3,4번 과정에서 반환받은 Socket에 input,output 스트림을 만들고 이것을 통해서 send() , recv() 합니다.

(5번 과정에 해당)

HashMap을 이용하기 때문에 InputStream을 통해서 ObjectInputStream을 만들어줍니다.

클라이언트의 요청을 처리하는 쓰레드

받은 HashMap을 사용하여 프로토콜( 파일업로드, 로그인요청, 채팅, 파일 다운로드 등.. ) 의 요청을 받아 처리합니다.

 

만약 클라이언트가 종료했다면 위 switch문에서 오류가 발생하면서 해당 클라이언트의 정보들을 모두 닫습니다. (6번에 해당)

 

 

클라이언트의 입장

클라이언트 소켓 생성

자바에서는 소켓객체를 생성하면서 파라미터로 ip주소와 포트번호를 주면 해당 주소의 서버에 접속하고 접속 성공한 Socket객체를 반환해 줍니다. ( 1번, 2번에 해당 )

 

서버에서 보내준 요청에대한 응답들을 받아서 처리하는 부분

서버가 클라이언트가 보낸 요청에 대한 처리결과를 보내주면 그것을 받는 부분입니다. ( 3번에 해당 )

그러다 오류가 발생하면 서버와에 연결 종료 ( 4번에 해당 )

 

마무리

 

혹시 코드가 필요하신분을 위해서 올렸습니다

ojdbc6.jar
2.61MB
Chatting.zip
0.06MB