Wanna be Brilliant Full-Stack Developer

JAVA 소켓통신 실습(스레드) 본문

Some Memos/Java

JAVA 소켓통신 실습(스레드)

Flashpacker 2023. 4. 25. 17:07

서버소켓이 있고 만번 포트로 기다리고 있다. 

그리고 클라이언트 소켓이 있다. 클라이언트 소켓이 연결을 요청을 하는데!

그때 필요한것이 ip와 포트라는것이 있다.

그러면 연결이 완료가 되면 서버소켓은 새로운 소켓을 만들고 그리고

새로운 소켓을 만들고나서 둘이 연결시키게 만드는 스트림을 만든다.

이전에는 클라이언트가 키보드로부터 스트림을 만들어서 키보드로부터 데이터를 입력받고

입력받고나서 그걸 바로 서버소켓쪽으로 데이터를 Write했다. 

그러면 서버소켓이 그 데이터를 Read했다. 이렇게하고나서 프로그램이 바로 끝난다.

이걸 끝내지 않기 위해서는 서로 계속 메시지를 보내기 위해서는 둘다 종료가 되면 안된다.

 

언제까지 종료가 되면 안되는가? 내가 원할때까지 계속 켜져 있어야한다.

그걸 위해서는 for인가 While인가? 이 로직은 while이 들어와야한다.

계속 메시지를 받으려면 while이 들어와야한다.

While문을 한번 돌려보자! 

서버소켓이 실행되고나서 연결은 한번만 받으면 된다.

클라이언트가 접속 대기중이고 accept하고 출력해어주는것이 반복되어 져야한다.

 

클라이언트 소켓은 연결을 하는것은 한번만 하면 된다. 

근데 버퍼를 계속 만들 필요는 없다. 버퍼는 한번만 만드면 된다.

계속 이렇게 데이터를 주고 받을 수 있다.

그러면 다시 그림에서 보면 클라이언트 소켓은 버퍼는 키보드로부터 입력받는 버퍼를 하나가 있어야하고 , 서버쪽으로 쓰기 버퍼가 하나 있어야한다.

서버소켓은 클라이언트로부터 입력받는 버퍼 하나만 있으면 된다.

이것들을 while문 안에 들어갈 필요가 없다. 

지금은 머만 할 수 있는가? 클라이언트가 서버소켓에게 메시지를 보내는거면 되는데

반대가 안된다.

서버가 클라이언트쪽으로 메시지를 써보고 싶은데? 지금 스레드를 보면 클라이언트입장에서는 메인 스레드가 

여기서 멈춰있다. 멈춰서 메시지를 받고 쓰고, 메인스레드가 바뻐서 다른일을 못한다.

서버도 보면 클라이언트로부터 메시지를 받고 화면에 출력하고 다시 while로 돌아와서 이걸 반복해서 이거밖에못한다.

이것만 할 수 있으니 무슨 문제가 있는가? 내가 쓸 수가 없다.

내가 서버 소켓 쪽에서는 글을쓸 수가 있는 스레드가 없다. 

클라이언트는 서버로부터 글을 읽을 수 있는 스레드가 없어서 다른일을 못한다

지금은 지극히 단방향 통신이다.

단방향 통신을 양방형 통신으로 바꾸기 위해서는 스레드가 필요하다.

 


양방향 통신을 위해서 스레드를 적용해보자!

클라이언트 입장에서는 쓰기고, 서버 입장에서는 읽기만된다. 이거를 메인스레드가 둘다 하고 있다.

그러면 반대 방향이 필요하다! 서버가 쓰기를 하고 싶고 클라이언트가 읽기를 하고 싶다.

그러면 먼가 다른 스레드가 필요하다. 

이걸 만들어보자! 첫번째로 버퍼부터 만드는것이 좋다.

서버쪽에서 쓰기 버퍼가 필요하다! 클라이언트쪽은 서버로부터 읽력 버퍼가 필요하다!

이 두 버퍼가 필요하고 데이터를 통신하기 위해서는 새로운 스레드가 필요하다!

 

서버쪽에서 BufferedWriter가 필요하다.

지금 메인스레드가 바쁘다. 그래서 쓰기 위한 새로은 스레드가 필요하다.

새로운 스레드를 만들기 위해서는 타겟이 필요한것이 기억하는가?

내부 클래스라는것이 있다.  내부 클래스를 하나 만들자!

implements Runnable 을 해주고 내부 클래스를 만들면 장점이 있다.

공유받을 수 있다.

근데 키보드로부터 입력도 받아야한다. BufferedReader도 필요하다?!

키보드로부터 읽어서 클라이언트한테 쓰는 버퍼 2개를 만들었다.

둘이서 같은 스레드를 쓰면 된다. 

While문은 메인 스레드의 역할이다, 메인 스레드가 While문을 돌기 전에? 

Thread t1 = new Thread(); 스레드를 하나 만들었다.

WriteThread 도 하나 만들어서 타겟을 넣어준다.

Write스레드를 실행한다.

메인 스레드는 새로운 스레드를 실행만 해주고 While문에 내려가서 일을 하고 새로운 write 스레드는 

이 Run 메소드의 일을 하고 있을것이다.

버퍼가 총 세개가 달렸다. 

새로운 스레드가 시작이 되면 while을 돌면서 keyboard로부터 데이터를 받는다. 

클라이언트도 데이터를 읽어야하니까 새로운 버퍼가 필요하다! 

BufferedReader를 만들어주고!

지금 메인스레드가 바쁘니까 새로운 글 읽기를 위한 스레드를 만든다! 

 

내부 클래스를 만들자!  타겟이 되려면 Runnable타입이여야한다.

글읽기 스레드가

이곳에서 실행 될것이다. 동시에 메인 스레드느느 While문을 계속 할것이다.

그러면 Run메서드에서는 글을 읽어야하니까 Stirng msg = br.readLine()이다. 키보드로부터 읽는것이 아니기 때문!

그런데 버그가 있다! 클라이언트에 ReadThread에 While이 없다?!


소켓통신을 마지막으로 배운 이유는?

웹도 소켓이다. 

네이버라고 하면!? 우리가 이제 클라이언트(여러분) , 일반 개인들이 브라우저라는걸 열면!?

브라우저라는 프로그램으로 연결을 웹소켓한테 요청을 한다.

연결이 되면 두번째로 하는것이 데이터를 달라고 한다.

그렇게 하면 양쪽으로 버퍼가 달릴것이다. 데이터를 주기만 하면 되니까 네이버쪽에서는 BufferedWriter가 달릴것이다.

클라이언트는 BufferedReader가 달릴것이다.

그리고 클라이언트의 주소 입력을 하기 위해서는 엔터도 해야하니까 키보드로부터 받는 BufferedReadr가 있을 것이다.

키보드로부터 메시지를 받고 www.naver.com  엔터를 치면 연결 요청을 하고 데이터 줘하고 요청을 한다.

그러면서 양쪽으로 Buffer가 달린다. 

그러면 네이버는 네임페이이지를 코드를 보면 이 엄청나게 많은 문자를 버퍼에 담아 돌려 보내준다!

HTML코드를 담아서 클라이언트한테 응답을 해준다.

어떻게 응답을 해줄 수 있는가? 서로한테 스트림이 달려 있기 때문이다.

어떤 스트림? 바이트 스트림이다. 방향은 한쪽으로 만간다. 네이버쪽에서 브라우저쪽으로 만 간다.

항상 flush만 하면서 데이터를 보내줄것이다. 클라이언트는 HTML코드를 받고 브라우저는 HTML코드를 받아서 그림을 그려준다. 

 

그리고 나서 소켓통신하고 다른것이 무엇인가하면? 기본 소켓 통신은 이 선이 한번 연결이 되면 계속 지속적으로 되어있어서 서로 메시지를 주고 받을 수 있다. 웹은 조금은 다르다.

웹은 어떻게 되는가 하면? 바이트 스트림을 통해서 메시지를 HTML코드를 다 돌려주고 나면 이 선을 끊어 버린다.

이게 웹통신 HTTP통신이다. HTTP통신의 근간? 부모가 무엇인가하면 소켓 통신이 근본이다. 

이 끊어 진다는것은 웹소켓 입장에서는 계속 연결할 필요가 없기 때문이다.

게쏙 연결을 유지하고 있으면 사용자가 엄청나게 많으면 네이버 입장에서는 부하가 엄청 크기 때문에

웹에서는 연결을 끊어버리는 정책, 상태가 지속되어 있지 않다고 해서 Stateless서버라고 한다.

 

소켓 통신은 상태가 계속 지속적으로 되어있다는것을 지속되어있다고 해서 statefull 서버라고 한다.

 

이 개념을 잘 잡고 있으면 웹을 할때 쉽게 할 수 있다.

 

'Some Memos > Java' 카테고리의 다른 글

JAVA 이벤트 리스너 원리  (0) 2023.05.24
JAVA 소켓 통신 #3 클라이언트 소켓  (0) 2023.04.25
Java 소켓통신 #2  (0) 2023.04.19
JAVA 소켓통신의 개념 #1  (0) 2023.04.13
Java BufferedReader란?  (0) 2023.04.13