넷응설 예습 스터디를 위해 소켓 프로그래밍에 대해 자료를 정리하던중 ... http와 TCP/IP소켓 웹소켓 등등 .. 비슷한듯 다른 개념들이 정리가 안되고 헷갈려가지고 한 번에 정리해보려한다. 이번 편은 소켓 위주. 다음 편은 웹소켓 위주일 듯 하다!
네트워크 위에서 프로그램이 동작하기 쉽게 하기 위해서 우리는 OSI 7계층을 나누어 네트워크를 관리함
(-) 계층만 나누는 걸로는 한계가 있음. 왜? 계층별 각 프로토콜은 일종의 통신 규약일뿐, 프로토콜 구현을 위해 안에 들어갈 구체적인 구현부인 함수가 필요함.
(+) 소켓에서 이러한 함수들의 body를 제공함 → 별도의 구현없이 소켓을 사용할 수 있음
즉, 프로토콜의 세부적인 명세를 일일히 정의할 필요없이 소켓을 활용하면 됨.
프로그램이 네트워크에서 데이터를 주고받을 수 있도록 네트워크 환경에 연결할 수 있게 만들어진 연결부
일반적으로 TCP/IP 프로토콜을 이용함
프로세스 간 통신에 사용되는 Socket을 이용한 통신 프로그래밍을 socket Programming이라고 한다.
Client Socket과 Server Socket로 구분되는데
통신 연결 요청을 받아들이는 Socket을 Server Socket,
통신 연결 요청을 보내는 Socket을 Client Socket이라고 한다.
동일한 구조의 Socket이지만, 역할에 따라 처리되는 흐름이 조금씩 다른 것 뿐이다.
연결 대상에 대한 정보가 들어있지 않은 Socket(껍데기 소켓)을 생성한다.
이 때 소켓의 종류를 선택해야하는데 TCP 소켓을 위해선 stream 타입을, UDP 소켓을 위해선 데이터그램 타입으로 지정이 가능하다.
연결하고 싶은 대상한테 '연결해줘!'라고 요청을 보낸다. IP주소와 서비스 포트 번호로 연결하고 싶은 타켓대상을 특정한다 -> 여기서의 ip와 port가 서버 소켓단의 ip와 포트를 말하는건가? ㅇㅇ 맞다.
요청을 보내고 단순히 끝나는게 아니고, 그 요청에 대한 결과가 돌아와야만 Connect의 실행이 끝난다
cf. 서비스 포트란!
연결 요청과 같이, 요청을 보낸다고 끝나는 게 아니라 요청에 대한 결과(신호)가 들어와야 실행이 끝난다.
But, 송신할 때에는 데이터를 보내는 것이기 때문에 데이터를 언제 얼마나 보낼것인지 알수 있지만, 수신할 때에는 상대방이 언제, 얼만큼의 데이터를 보낼 것인지 알수가 없다는 서로의 차이점이 존재한다.
그렇기 때문에 수신하는 API는 별도의 Thread에서 진행하게 된다.
더 이상의 데이터 송수신이 없다고 판단되면 소켓을 닫는다.
내가 만약 곽블링언니(✨)에게 카톡을 보냈다면 블링언니만 그 카톡을 볼 수 있어야한다. 사적인 메세지가 온 동네에 퍼지면 당연히 안되기 때문!!
즉, 내가 어떤 데이터를 보내려고 할 때, 수신측에서 무작정 데이터를 수신하는게 아니라 포트번호를 식별하여 알맞게 들어온 프로세스만을 수신하여야한다.
클라이언트 소켓과 마찬가지로 연결 대상에 대한 정보가 들어있지 않은 껍데기 소켓을 생성한다.
우리는 컴퓨터를 사용할 때 매우 많은 서비스를 이용한다. 즉, 수많은 프로세스가 동시에 돌아가고 있다.
만약 서버 소켓이 받은 데이터를 다시 보내주어야할 때 프로세스들의 포트번호가 동일하다면 혼란이 생길 수 있다. 따라서 서버 소켓이 고유한 포트 번호를 만들 수 있도록 소켓과 포트번호를 결합해주는 작업이 필요하다.
위의 그림과 같이 소켓이 사용하는 포트 번호가 다른 소켓의 포트 번호와 중복된다면 어떤 상황이 될까? 모든 소켓이 10000 이라는 동일한 포트 번호를 사용하게 된다면, 네트워크를 통해 10000 포트로 데이터가 수신될 때 어떤 소켓이 처리해야 하는지 결정할 수 없는 문제가 발생할 것이다. 이런 이유로 운영체제에서는 소켓들이 중복된 포트 번호를 사용하지 않도록, 내부적으로 포트 번호와 소켓 연결 정보를 관리한다.
참고로! 하나의 프로세스는 동일한 포트 번호를 가진 여러 개의 소켓을 결합 할 수 있다. 즉, 호스트가 하나의 Port로 여러 개의 Socket을 만들어 다른 호스트들과 데이터를 주고받을 수 있다.
이러한 이유 덕분에 우리가 하나의 채팅 앱을 사용하더라도 동시에 많은 사람들과 채팅을 주고받을 수 있는 것이라고 생각한다. 😄
그러니까 특정 포트가 소켓을 여러개 열어서 첫번째 소켓으로는 엄마.. 두번째 소켓으로는 아빠... 세번째 소켓으로는 동생과 카톡할 수 있게 되는 원리라고 생각하면 될 것 같다.
서버 소켓에서 포트번호와 바인딩 작업을 마치고 나면 클라이언트로부터의 연결 요청을 받아들일 준비가 된 것이다.
클라이언트가 연결 요청을 할 때까지 기다리다가 연결 요청이 오면 대기 상태를 종료하고 리턴한다.
실질적인 연결은 여기서 시작된다(!)
서버소켓은 사실.. 연결 요청을 받아들임과 동시에 새로운 소켓을 생성한다.
서버 소켓의 메인 역할은 just 클라이언트 연결 요청을 기다리는 것이다. 따라서 클라이언트 소켓으로부터 연결 요청을 받으면 새로운 소켓을 열고, 이것과 클라이언트 소켓을 맵핑하여 넘겨준다.
클라이언트와 동일함.
클라이언트와 동일함. 하지만 서버 소켓은 자신이 생성한 소켓들도 관리를 해야한다!
참고자료
https://www.youtube.com/watch?v=MPQHvwPxDUw
https://recipes4dev.tistory.com/153
https://www.youtube.com/watch?v=8Ql1l048MD8
https://mingule.tistory.com/m/60
내용에 오류가 있다면 댓글로 알려주세요 🐶
소켓 이해하는데 도움 넘 되었어요 감사합니다