Java 기반 클라우드 융합 개발자 과정 - KH 정보교육원/5월

22. 05. 09 - 네트워크 프로그래밍( SeverSocket, Socket ) // feat. Queue, List

giggs 2022. 5. 12. 18:46

 

저번 시간 실습했던 네트워크 프로그래밍 코드로 알아보기!

  • chatPrjGroup 코드 중심으로 알아보기

 

 

 

chatPrjGroup 

  • 기본 프로세스 내용 – 클라이언트 하나한테 내용받아서 전체한테 뿌려준다.
  • 먼저 서버쪽에서 어떻게 돌아가는지 확인해보자

 

 

 

1번 - server패키지 - Main클래스

 

 

 

 

 


 

 

15-16번 Line 객체 2개 만들었다.

  • 보낼 메시지를 쌓아 둘 - Queue타입 객체 msgQueue
  • 메시지를 보낼 통로 Stream인 - List 타입 객체 bwList

 

 

 


 

 

21번 라인 - 서버 소켓 만들었다.

  • ( 그냥 소켓 X ) - 서버 소켓은 연결 요청이 오면 새로운 소켓을 만들어서 연결해주는 친구이다.

 

 

 

 


 

 

@ 개념 플러스 +

 

  • 클라이언트의 그냥 소켓이 서버 소켓에 연결 요청을 하는 것은 맞지만
  • 서버 소켓과 직접 연결이 되는 것이 아닌
  • 서버 소켓이 만들어준 새로운 소켓과 연결되어서 데이터를 주고받는 것이다.

 

 

 

서버 소켓에 연결을 요청하는 것이고, 

실제 연결은 서버 소켓이 만들어준 소켓에 연결되어서 주고받는 것

소켓과 소켓은 1:1 방식으로 연결

 

 

 


 

 

 

24번 라인  SeverSender thread 생성하고 - 일 시작 명령 

  • 작업 1번만 실행 – 모든 클라이언테에게 메시지 보내는 작업
  • ServerSender객체가 무슨 일 하는지는 아래에서 체크

 

 

 

 


 

 

 

26~28번라인  while

  • 26번 : 무한반복 → 27번 : 출력 →
  • 28번 : 소켓 연결 요청 들어오면 accept() 해서 새로운 소켓을 만들어 주고 연결
  • 연결된 클라이언트 쪽 소켓의 정보를 Socket 타입 s 변수에 저장 ( ServerSocket 타입 아님! check )

 

 

 

 

 

 

29번 라인> 연결 요청한 소켓 ip 출력해주고

 

31번 라인> 어떤 쓰레드하나 만들어주고 start 해준다

  • SeverReader객체를 실행하는 쓰레드
  • while - 무한 반복 안에 있다 - 반복 작업

 

32번라인 > 어떤 리스트에다가  뭘 담았냐면  outputStream을 한 칸 한 칸 담아준 것이다. -

  • 메시지를 보낼 통로 Stream인 - List 타입 객체 bwList 에다가 뭘 담았냐면
  • outputStream을 한 칸 한 칸 담아준 것이다. 

 

 

 


 

전체 코드 확인

 

 

server 패키지 - Main.Class

 

 

 

 

 


 

 

 

server패키지 -

1번 : SeverSender,

2번 : ServerReader 코드 살펴보기

 

 

 

 

 

 

 

먼저 그림으로 흐름 확인

 

 

 

 

 

## 참조 코드 - Main.Class에서 생성한 객체 

 

 

 

클라이언트에서 서버로 들어오는 메시지들을 queue 타입 객체 msgQueue에 쌓아놓았다.

-> 이것을 뿌려주는 애 필요하다 

-> Sender Thread 만들어서 뿌려주는 기능 담당하게 한다 

-> 맨 앞에 있는 애 꺼내와서 모두에게 뿌려준다.

-> 이 작업을 모든 클라이언트에게 해줄 때까지 - 반복

 

 

 

 

 

 

 

 

 


 

 

 

 

1번. ServerSender 클래스 코드 확인 

 

  • implements Runnable 확인 - run() 메서드 구현
  • 쓰레드 만든 목적 = 기능 하나 담당하게 해 주기 위해서
  • 무슨 기능?
  • 받은 메시지를 전체 클라이언트에게 뿌려주는 작업시키기 위해서 생성

 

 

 

 

 

 

14 - 반복 작업할 것이다.

15 - 쉬는 시간 조금 주고 ( 자원 계속 사용 중인 상태 방지 + interrupt나 예외상황 처리할 시간 준다) 

16 - msg 변수에 Main에서 메시지 쌓아놓은 msgQueue의 데이터 하나 꺼내오기 poll

17 - 꺼내온 메시지가 없다면 (비었다면) 밑에 쪽으로 안 가고 계속 다시 반복하도록 continue;

18~21 - 꺼내온 메시지가 비어있지 않았다면 실행되는 부분

18 - 향상된 for 문 BufferedWriter 타입 bw에 Main에 있는 bwList에 있는 스트림을 하나하나 넣어준다. ( 끝까지 반복 )

  • 메시지를 보낼 통로 Stream인 - List 타입 객체 bwList

19~21 - 메인에서 받은 스트림을 통해 - write 써주고 / newLine 개행하고  / flush  밀어주고 작업 처리 

 

 

 

 

 

 

>메시지 가져온 건 알겠는데 - poll();로 가져왔다.

>통로는 어떻게 가져온 것인가? -Main.bwList에 다 들어있다.

 

 

 

 

 

> bwList 는 소켓에서 가져온 outputstream을 기반으로 만들어진 애

>Main.bwList가 서버 소켓에 연결된 소켓의 스트림을 가지고 있다.

>그거를 통해서 보내주는 것 

 

 

 

 

 


 

 

 

 

2번. ServerReader 클래스 코드 확인 -

 

 

  • 서버 리더는 어떤 역할?
  • 클라이언트 소켓에서 입력되는 메시지 계속 받아오고 – 써주는 역할
  • Main에 메시지 쌓아놓는 queue타입 msgQueue 객체에 - 계속 써주는 역할

 

 

 

 

 

14~15 - 서버로부터 받은 클라이언트의 소켓 정보를 이용해서 초기화

23 - 넘어온 클라이언트 소켓과 연결하기 - 스트림 생성

24~28 - 반복 작업 - 스트림으로 읽어온 메시지를 Main.msgQueue에 입력해주기

 

 

 

 

 

 

서버 쪽 확인 끝

 

 

 

 

 

 

 


 

 

 

 

클라이언트 쪽 확인해보자

 

 

 

 

 

 


 

 

 

 

1번 - client - Main.Class 살펴보기

 

 

 

 

 

19~27번 라인 - 사용자에게 이름 / ip / port 입력받기

 

30번 라인 소켓 만들어서 연결 ( 사용자에게 입력받은 ip주소와 port번호로 연결 )

 

32/33번 라인 어떤 쓰레드 만들어서 실행해주는 것

  • Sender 와 Reader 쓰레드 생성해서 start() 실행

 

 

 

 

 


 

 

 

 

 

Sender ThreadReader Thread살펴보자

 

 

 

 

 

2번 - Sender Thread

  • 메시지 하나 읽어와서 write / flush 무한 반복 - 이게 끝

 

 

 

 

 

 

 


 

 

 

3번 - Reader Thread

  •  읽고 / 출력하고 무한반복한다 -

 

 

 

 

23번 라인 - 쉬는 시간 잠깐이라도 주어야 

  • 계속 자원 사용하는 것 방지, 효율성 증대
  • interrrupt 발생했을 때 끝나도록 

 

 

 

 

 


 

 

 

 

+@ chatPrj 코드 설명

 

여기서는 읽는 친구 / 쓰는 친구 따로따로 만들어서 작업했다.

쓰레드 하나하나가 소켓 정보를 알 수 있도록 작업해준 것..

destroy() 메서드는 뭔가 문제가 발생했을 때

종료되지 않고, 자원 처리하도록 작업해준 내용이다

굳이 신경 안 써도 괜찮다.

 

이 부분은 한글파일 참조! ㅎㅎ

 

이것으로 네트워크 프로그래밍까지 끝!

 

 

 

 

 


 

 

 



review


저번 시간에는 네트워크 프로그래밍을
실행하는 방법과 순서, 서버와 클라이언트 소통하는 방식을 배웠고
이번 시간에는  
그것들이 어떻게 이루어지는지
서버 소켓, 소켓, 스트림 등을 살펴보면서 알아보았다.

일단 서버 소켓을 실행시켜주어서 서버를 열어주고
클라이언트 소켓들을 이용하여 연결 요청 
 accept() 하면 서버 소켓이 만들어주는 new Socket에 연결

Thread를 이용 - 서버와 클라이언트 쪽에서 메시지를 받고, 보내고 작업해준다.
queue를 이용 - FIFO 특징 - 메시지를 넣어놓고
List를 이용 - BufferedWriter 스트림을 관리

이해한 내용을 써보니 쉽게만 보이네..
직접 코드를 짜보라 그러면 고생 좀 할 것 같다.
이게 기본일 텐데 ㅜㅜ
다시 한번 쭉 보면서
큰 흐름을 파악하고 필요한 기능과 순서를 짜 보도록
연습해 보아야겠다.

나중에는 메시지를 받고 보내고 하는 부분이
파일이나 cmd창이 아닌 DB를 이용해서 하겠지? ㅎㅎ
DB 쪽도 빨리 배워서 활용해 보고 싶다.