[networking] 소켓 API accept () 함수는 어떻게 작동합니까?

소켓 API는 TCP / IP 및 UDP / IP 통신에 대한 사실상의 표준입니다 (즉, 우리가 알고있는 네트워킹 코드). 그러나 핵심 기능 중 하나 accept()는 약간 마술 적입니다.

반 공식적인 정의를 빌리려면 :

accept ()는 서버 측에서 사용됩니다. 원격 클라이언트에서 새 TCP 연결을 만들기 위해 수신 된 수신 시도를 수락하고이 연결의 소켓 주소 쌍과 관련된 새 소켓을 만듭니다.

즉, accept서버가 새로 연결된 클라이언트와 통신 할 수있는 새 소켓을 반환합니다. 이전 소켓 ( accept호출 된)은 동일한 포트에서 열린 상태로 유지되어 새 연결을 수신합니다.

어떻게 accept작동합니까? 어떻게 구현됩니까? 이 주제에 대해 많은 혼란이 있습니다. 많은 사람들이 accept가 새 포트를 열고이를 통해 클라이언트와 통신한다고 주장합니다. 그러나 새 포트가 열리지 않기 때문에 이것은 분명히 사실이 아닙니다. 실제로 다른 클라이언트와 동일한 포트를 통해 통신 할 수 있지만 어떻게해야합니까? 여러 스레드 recv가 동일한 포트에서 호출 할 때 데이터가 어디로 가야하는지 어떻게 알 수 있습니까?

소켓 설명자와 연결되는 클라이언트 주소의 줄을 따라가는 것 같고 데이터가 올 때마다 recv올바른 소켓으로 라우팅되지만 확실하지 않습니다.

이 메커니즘의 내부 작동에 대한 철저한 설명을 얻는 것이 좋습니다.



답변

당신의 혼란은 소켓이 서버 IP : 서버 포트로 식별된다는 생각에 있습니다. 실제로 소켓은 4 개의 정보로 고유하게 식별됩니다.

Client IP : Client PortServer IP : Server Port

따라서 허용되는 모든 연결에서 서버 IP와 서버 포트는 일정하지만 클라이언트 측 정보는 모든 것이 진행되는 위치를 추적 할 수 있도록합니다.

사물을 명확히하는 예 :

에 서버 하나 192.168.1.1:80와 클라이언트 두 개가 10.0.0.1있고 10.0.0.2.

10.0.0.1로컬 포트에서 연결을 열고 1234서버에 연결합니다. 이제 서버에는 다음과 같이 식별되는 하나의 소켓이 있습니다.

10.0.0.1:1234 - 192.168.1.1:80

이제 10.0.0.2로컬 포트에서 연결을 열고 5678서버에 연결합니다. 이제 서버에는 다음과 같이 식별되는 두 개의 소켓이 있습니다.

10.0.0.1:1234 - 192.168.1.1:80
10.0.0.2:5678 - 192.168.1.1:80


답변

사용자 “17/26″이 제공 한 답변에 추가하기 위해

소켓은 실제로 5 개의 튜플 (소스 IP, 소스 포트, 대상 IP, 대상 포트, 프로토콜)로 구성됩니다. 여기서 프로토콜은 TCP 또는 UDP 또는 모든 전송 계층 프로토콜이 될 수 있습니다. 이 프로토콜은 IP 데이터 그램의 ‘프로토콜’필드에있는 패킷에서 식별됩니다.

따라서 서버의 서로 다른 응용 프로그램이 정확히 동일한 4- 튜플에서 동일한 클라이언트와 통신하지만 프로토콜 필드가 다른 경우가 가능합니다. 예를 들면

서버 측의 Apache (TCP의 server1.com:880-client1:1234) 및 World of Warcraft (UDP의 server1.com:880-client1:1234)

클라이언트와 서버 모두 다른 4 개의 필드가 모두 동일하더라도 두 경우 모두 IP 패킷의 프로토콜 필드가 다르므로이를 처리합니다.


답변

제가 이것을 배울 때 저를 혼란스럽게했던 것은 용어 socketport그것들이 물리적 인 것임을 암시한다는 것이 었 습니다. 사실 그것들은 네트워크의 세부 사항을 추상화하기 위해 커널이 사용하는 데이터 구조 일뿐입니다.

따라서 데이터 구조는 다른 클라이언트와의 연결을 분리 할 수 ​​있도록 구현됩니다. 에 관해서는 어떻게 그들이 구현하고, 답은이.)는, 소켓 API의 목적은 구현이 단지 모양이없는 문제 또는 b합니다.) 정확하게하는 것이 문제가되지이다 않습니다 중 하나입니다. 하나의 구현에 대한 자세한 설명을 제공하는 강력 추천 Stevens 책 외에도 Linux 또는 Solaris 또는 BSD 중 하나의 소스를 확인하십시오.


답변

다른 사람이 말했듯이 소켓은 4- 튜플 (클라이언트 IP, 클라이언트 포트, 서버 IP, 서버 포트)로 고유하게 식별됩니다.

서버 IP에서 실행되는 서버 프로세스는 활성 소켓의 데이터베이스 (사용하는 테이블 / 목록 / 트리 / 어레이 / 매직 데이터 구조는 상관 없음)를 유지하고 서버 포트에서 수신합니다. 서버의 TCP / IP 스택을 통해 메시지를 수신하면 데이터베이스에 대해 클라이언트 IP 및 포트를 확인합니다. 클라이언트 IP 및 클라이언트 포트가 데이터베이스 항목에서 발견되면 메시지는 기존 처리기로 전달됩니다. 그렇지 않으면 새 데이터베이스 항목이 생성되고 해당 소켓을 처리하기 위해 새 처리기가 생성됩니다.

ARPAnet의 초기에는 특정 프로토콜 (FTP)이 연결 요청에 대해 지정된 포트를 수신하고 핸드 오프 포트로 응답했습니다. 해당 연결에 대한 추가 통신은 핸드 오프 포트를 통해 이동합니다. 이는 패킷 당 성능을 개선하기 위해 수행되었습니다. 당시 컴퓨터는 몇 배 더 느 렸습니다.


답변