먼저 NIC는 패킷을 메모리에 기록합니다. CRC 검사를 수행하여 패킷이 유효한지 확인한 다음 패킷을 호스트의 메모리 버퍼로 보냅니다. 이 버퍼는 드라이버가 커널에 이미 요청한 인 메모리이며 패킷 수신을 위해 을 할당합니다. 버퍼가 할당되면 드라이버 은 NIC에 대한 메모리 주소와 크기를 알려줍니다. NIC이 패킷을 수신하더라도 드라이버가 할당 한 호스트 버퍼가 없으면 NIC가 패킷을 삭제할 수 있습니다.
호스트 메모리 버퍼로 패킷을 보낸 후 NIC는 인터럽트를 호스트 OS로 보냅니다.
그런 다음 드라이버는 새 패킷을 처리 할 수 있는지 여부를 확인합니다. 지금까지 제조업체에서 정의한 드라이버 NIC 통신 프로토콜이 사용되었습니다.
드라이버가 패킷을 상위 계층으로 보내야하는 경우 패킷 은 OS가 패킷을 이해하는 OS 용으로 사용하는 패킷 구조로 포장해야합니다. 예를 들어 Linux의 sk_buff, BSD 계열 커널의 mbuf 및 Microsoft Windows의 NET_BUFFER_LIST는 해당 OS의 패킷 구조입니다. 드라이버는 랩핑 된 패킷을 상위 계층으로 보냅니다.
이더넷 계층은 패킷이 유효한지 확인한 다음 이 상위 프로토콜 (네트워크 프로토콜)을 역 다중화합니다. 이때 은 이더넷 헤더의 ethertype 값을 사용합니다. IPv4 ethertype 값은 0x0800입니다. 이더넷 헤더를 제거한 다음 패킷을 IP 계층으로 보냅니다.
IP 계층은 패킷이 유효한지 여부도 확인합니다. 즉, 은 IP 헤더 체크섬을 확인합니다. 논리적으로는 이 IP 라우팅을 수행하고 로컬 시스템이 패킷을 처리하게할지 여부를 으로 결정하거나 패킷을 다른 시스템으로 보냅니다. 로컬 시스템에서 패킷을 으로 처리해야하는 경우 IP 계층은 IP 헤더의 프로토 값을 참조하여 상위 프로토콜 (전송 프로토콜)을 역 다중화합니다. TCP 프로토콜 값은 6입니다. IP 헤더를 제거한 다음 패킷을 TCP 계층으로 보냅니다.
하위 레이어와 마찬가지로 TCP 레이어는 패킷이 유효한지 확인합니다. 또한 TCP 체크섬을 확인합니다. 앞에서 언급했듯이 현재 네트워크 스택은 체크섬 오프로드를 사용하므로 TCP 체크섬은 커널이 아닌 NIC가 계산 한 입니다.
그런 다음 패킷이 연결된 TCP 제어 블록을 검색합니다. 패킷 중 <source IP, source port, target IP, target port>
이 식별자로 사용됩니다. 연결을 검색 한 후 은 패킷을 처리하기 위해 프로토콜을 수행합니다. 새로운 데이터를 수신하면 수신 소켓 버퍼에 데이터를 추가합니다. TCP 상태에 따르면 새 TCP 패킷 (예 : ACK 패킷)을 보낼 수 있습니다. 이제 TCP/IP 수신 패킷 처리가 완료되었습니다.
수신 소켓 버퍼의 크기는 TCP 수신 창입니다. 특정 지점에 수신 창을 큰 경우 TCP 처리량이 증가합니다. 과거에는 소켓 버퍼 크기가 응용 프로그램 또는 OS 구성에서 조정되었습니다. 최신 네트워크 스택에는 수신 소켓 버퍼 크기를 조정하는 함수 (예 : 수신)가 자동으로 있습니다.
응용 프로그램에서 읽기 시스템 호출을 호출하면 영역이 커널 영역에 대해 으로 변경되고 소켓 버퍼의 데이터가 사용자 영역의 메모리에 복사됩니다. 복사 된 데이터는 소켓 버퍼에서 제거됩니다. 그런 다음 TCP가 호출됩니다. 소켓 버퍼에 새 공간이 있으므로 TCP는 수신 창을 늘립니다. 그리고 프로토콜 상태에 따라 패킷을 보냅니다. 패킷이 전송되지 않으면 시스템 호출이 종료됩니다.