Loading
2022. 5. 30. 00:42 - lazykuna

한 서버가 어떻게 16K 이상의 연결을 맺을 수 있을까?

먼저 결론부터 말하자면, 제가 서버-클라이언트 사이의 연결 방법에 대해서 완전히 잘못 알고 있었습니다. 😂 지금까지 제대로 몰랐다는 사실에 아주 깊은 반성을…

사실 이건 예전부터 궁금했던 내용이긴 한데, 최근 테크논문들을 읽으면서 의심이 깊어집니다. 그러니까, 저는 “서버가 연결을 받을 포트 하나를 오픈해 두고, 클라이언트가 연결될때마다 포트를 하나씩 쓴다면, 포트의 최대값이 16K(65536)인 것은 자명하니까, 약 6만개 이상의 커넥션을 동시에 맺을 수 없지 않나?” 라는 의구심을 가지고 있었습니다.

그래서 오늘 좀 찾아 봤는데, 당연히 아니었습니다! 그러니까, 서버가 소켓을 열고 나서 클라이언트가 접속을 시도할 때, 클라이언트는 자신의 소켓을 열어서 그것을 서버에게 전달해 주는 구조라고 합니다. 그리고 클라이언트와 서버는 각각의 포트(=창구)를 통해서 통신하게 되는 것입니다. 즉! 서버 포트 하나에 여러 클라이언트가 붙어서 통신하는 구조입니다. 저는 그동안 포트 하나에 클라이언트 하나 붙어 통신하는 아스트랄한 구조인 줄…

https://stackoverflow.com/questions/44605797/in-a-tcp-connection-how-possibly-can-a-server-handle-more-than-65535-client-at

https://stackoverflow.com/questions/2439472/how-the-clients-client-sockets-are-identified

좀 더 구체적으로 들어가 보면, 클라이언트 TCP 소켓에서 연결을 처음 시도할 때 SYN 패킷을 보낼 때부터 봅시다. (첫번째 스탭)

그리고 TCP 패킷에는 송신자의 포트 정보, 그리고 이를 덮어싸는 IP 정보도 같이 들어 있습니다.

그래서 이걸 통해 어떤 클라이언트에서 패킷이 전달되었는지를 확인할 수 있습니다. 커널에서 이를 잘 감싸주어 accept() 하여 fd 로서 간편하게 다룰 수 있게 해주고, epoll() 과 같은 메서드 I/O multiplexing 같은 걸 제공해주는 것입니다.

  • Notify에 대한 자세한 설명은 이 논문을 참조 할 수 있습니다. 특히 4 챕터에 소름 끼치도록 Packet receive시 발생하는 일이 상세하게 적혀 있습니다.

오늘의 오해 끝.