소켓 프로그래밍 1 - binding

프로그래밍 2022. 6. 19. 21:43

요즘은 대부분 Socket 자체를 이용해서 programming 하시는 분은 많이 없을 거라고 생각합니다.
하지만 대부분의 software가 network상에서 동작을 하고 있으니 모두 socket을 이용하고 있다고 봐도 되겠습니다.
그래서 Socket Programming의 기본에 대해서 얘기해 보려고 합니다.

전공이 아니니 개발자 입장에서 알고 있는것만 가볍게...

SOCKET

우리가 늘 전기 소켓을 연결해 전기를 사용할 수 있듯이 Software도 network에 연결하기 위하여 socket을 사용합니다.
Software가 컴퓨터에 저장되어 있는 파일을 다룰 때에는, file에 대한 정보를 저장하고 가르키는 File Descriptor를 이용해서 읽고 쓰기를 하게 됩니다. 그런데 Socket도 File과 마찬가지로 Socket Descriptor를 이용해 Socket를 다루게 됩니다. Socket과 Socket Descriptor에 대한 상세한 내용은 인터넷 상에 이미 많은 posting이 있으니 여기서는 생략합니다.


우선 가장 기본적인 Server/Client 간의 Socket API 사용 순서에 대해 알아 보겠습니다.

TCP/IP Server, Client 간 Socket API 호출 순서

 

서버측의 준비 과정

1. Socket

Socket을 생성하는 단계 입니다. File을 다룰 때에 File 에 대한 정보를 저장할 공간을 마련하고 그것을 handling 하기 위해 File descriptor를 생성하는 것처럼 Socket도 정보를 담을 공간을 마련하고 그것을 handling 하기 위해서 Socket descriptor를 준비하는 단계입니다.

2. * Bind *

Bind에 별표를 쳤습니다. 매우 중요한데 쉽게 넘어가기 쉬운 부분이기도 합니다.
"bind 과정은 PORT 를 사용하도록 연결해 주는 것" 이라고 정의를 내리는 글들을 많이 보았습니다.
그런데 정확히 말하면 "주소(Address)와 포트(Port)"를 사용할 수 있도록 연결해 주는 것이고...
port도 중요하지만 사실은 Address 가 더 중요하다고 얘기하고 싶네요.
서버의 Bind 단계에서 주소는 무엇을 의미할까요?
우리가 Command창에서 ipconfig 를 실행해 보면 아래와 같이 여러가지 network 어댑터를 볼 수가 있습니다.

실제 Lan card 어댑터에 할당된 주소, 가상 네트웍 어댑터에 할당된 주소, 무선 어댑터에 할당된 주소....
이런 다양한 어댑터와 할당된 주소들을 통해, software는 각각의 서로 다른 network에 연결할 수 있 있습니다.
그렇다는 얘기는 각각의 서로 다른 network에 속해 있는 서로 다른 Client들이 모두 서버로 연결할 수도 있다는 의미 이기도 합니다.

위 그림은 내 컴퓨터에 연결되어 있는 이더넷 어댑터의 주소가 172.18.192.1 이고 무선 어댑터의 주소가 192.168.219.109 라는 것을 의미합니다.

A. 컴퓨터가 무선 인터넷을 사용하도록 설정되어 있다고 가정해 봅시다.
만약 software가 socket정보에 Address 172.18.192.1 와 PORT(8080)으로 설정하고 bind를 실행하면 어떨까요?
그러면 무선 네트웍트로 연결된 Client 들은 서버로 연결을 할 수가 없게 되고 이더넷에 연결된 Client들 만 연결이 가능해 집니다. 서버가 설정한 주소는 무선 어댑터의 주소가 아니기 때문에 무선 어댑터를 통해서는 PORT에 접근할 수가 없기 때문이지요.
물론 반대의 경우도 마찬가지입니다.

B. 그러면 모든 어댑터에서 들어오는 Client의 연결 요청을 허용하려면 어떻게?
bind시 사용하는 Socket 구조체의 Address 정보를 INADDR_ANY로 입력하면 됩니다.
INADDR_ANY는 현재 컴퓨터에 연결된 모든 어댑터로 들어오는 Client 요청을 받아 들이겠다는 의미입니다.
우리가 당장 Command 창에서 "netstat -an" 을 실행해 보면

netstat -an

위 그림에서 볼 수 있는 "0.0.0.0", "127.0.0.1", "192.168.219.109" 들이 Address에 해당합니다.
그리고 그 중에 "0.0.0.0" 이 바로 INADDR_ANY에 해당합니다.
위 그림의 예에서 0.0.0.0:22 LISTENING 은 모든 어댑터로부터 Client요청을 받겠다는 의미이겠죠.

그러면 127.0.0.1 은? 바로 loopback 어댑터에 해당하며 ipconfig 명령에는 보이지 않지만 컴퓨터 내부에서만 연결이 가능한 폐쇄된 주소 정도로 인지하고 있으면 될 것 같네요.
위 그림의 127.0.0.1:16106 LISTENING은 어떤 Server 가 Local 컴퓨터 내부에서 연결이 가능하도록 16106 port를 Listen하고 있다는 의미가 됩니다.
일반적으로 윈도우 booting시 동작하는 일부 서비스들이 이와 같이 내부에서만 연결을 허용하는 형태의 서버로 실행합니다.

만약 현재 무선 어댑터를 사용중이라면 위 그림에서 이더넷 주소 172.18.192.1:139 로 LISTENING 하는 software는 어떤 Client의 연결도 현재 받을 수 없는 상태일 겁니다.

그러면 위 그림의 192.168.219.109:49412 40.90.189.152:443 ESTABLISHED 는 뭘까요?
현재 무선 네트웍으로 40.90.189.152 .의 주소를 가지는 컴퓨터가 49412 port를 listen하고 있는 내 컴퓨터의 서버에 연결을 했다는 의미입니다.

3. Listen

서버 PORT를 Open하고 Client로 부터 연결을 대기하는 상태입니다.
그리고 127.0.0.1 로 2000번 포트를 쓰고  있으면 다른 어댑터의 주소로 2000번을 또 쓸수는 없습니다. 즉, port는 컴퓨터 전역으로 하나만 할당이 가능합니다.
한 가지 중요한 것은 Listen 동작은 TCP에만 있다는 것입니다. UDP에는 없지요. 왜 그럴까요?
그건 다음 기회에....



여기까지 일단 Server 측의 Socket 준비 단계에 대해 알아 보았습니다.
TCP 기반의 설명이라는 것을 꼭 기억하시기 바랍니다. UDP는 Server의 개념이 없습니다.
다음에는 Client쪽을 알아 보도록 하겠습니다.
참고로 제일 위의 그림에 보시면 Client는 Bind 과정이 없습니다.

그런데... 과연 Client에는 bind 과정이 정말로 없는 것일까요?


TO BE CONTINUED...

728x90
반응형

'프로그래밍' 카테고리의 다른 글

소켓 프로그래밍 3 - Accept  (0) 2022.06.22
소켓 프로그래밍 2 - Client와 Port Range  (0) 2022.06.21
DI, DIP 그리고 IOC  (0) 2022.06.15
조제프 푸리에(Joseph Fourier)  (1) 2022.06.15
트랜지스터  (0) 2022.06.15
admin