대역 외 데이터 Protocol-Independent

스트림 소켓 추상화에는 OOB(대역 외) 데이터의 개념이 포함됩니다. 많은 프로토콜을 사용하면 들어오는 데이터의 일부를 어떤 식으로든 특수로 표시할 수 있으며 이러한 특수 데이터 블록을 일반 시퀀스에서 사용자에게 전달할 수 있습니다. 예를 들어 X.25 및 기타 OSI 프로토콜의 신속한 데이터와 BSD UNIX의 TCP 사용에 대한 긴급 데이터가 있습니다. 다음 섹션에서는 프로토콜 독립적 방식으로 OOB 데이터 처리를 설명합니다. TCP 긴급 데이터를 사용하여 구현된 OOB 데이터에 대한 설명은 프로토콜 독립적 설명을 따릅니다. 각 토론에서 recv 의 사용은 recvfrom, WSARecvWSARecvFrom을 의미하며 WSAAsyncSelect 에 대한 참조도 WSAEventSelect에도 적용됩니다.

프로토콜 독립 OOB 데이터

OOB 데이터는 연결된 스트림 소켓의 각 쌍과 연결된 논리적으로 독립적인 전송 채널입니다. OOB 데이터는 일반 데이터와 독립적으로 사용자에게 배달될 수 있습니다. 추상화는 OOB 데이터 기능이 한 번에 하나 이상의 OOB 데이터 블록의 안정적인 배달을 지원해야 한다고 정의합니다. 이 데이터 블록은 하나 이상의 데이터를 포함할 수 있으며, 한 번에 하나 이상의 OOB 데이터 블록이 사용자에게 배달 보류 중일 수 있습니다. 대역 내 신호(예: 긴급 데이터가 일반 데이터와 함께 순서대로 전달되는 TCP)를 지원하는 통신 프로토콜의 경우 시스템은 일반적으로 일반 데이터 스트림에서 OOB 데이터를 추출하고 별도로 저장합니다(일반 데이터 스트림의 간격을 유지). 이를 통해 사용자는 OOB 데이터를 순서대로 수신하고 중간 데이터를 모두 버퍼링하지 않고 순서대로 수신 중에서 선택할 수 있습니다. OOB(대역 외) 데이터를 피킹할 수 있습니다.

사용자는 SIOCATMARKIOCTL과 함께 ioctlsocket 또는 WSAIoctl 함수를 사용하여 OOB 데이터가 읽기를 기다리고 있는지 확인할 수 있습니다. TCP와 같이 일반 데이터 스트림 내에서 OOB 데이터 블록의 위치 개념이 의미 있는 프로토콜의 경우 Windows Sockets 서비스 공급자는 일반 데이터 스트림 내에서 OOB 데이터의 마지막 바이트 위치를 나타내는 개념적 마커를 유지 관리합니다. 이는 SIOCATMARK를 지원하는 ioctlsocket 또는 WSAIoctl 함수의 구현에 필요하지 않습니다. OOB 데이터의 존재 또는 부재가 모두 필요합니다.

일반 데이터 스트림 내에서 OOB 데이터 블록의 위치 개념이 의미 있는 프로토콜의 경우 애플리케이션은 일반 데이터 스트림의 일부로 대역 외 데이터를 인라인으로 처리할 수 있습니다. 이는 setsockopt 함수를 사용하여 소켓 옵션을 SO_OOBINLINE 설정하여 수행됩니다. OOB 데이터 블록이 일반 데이터 스트림과 완전히 독립적인 다른 프로토콜의 경우 SO_OOBINLINE 설정하려고 시도하면 오류가 발생합니다. 애플리케이션은 SIOCATMARKIOCTL과 함께 ioctlsocket 또는 WSAIoctl 함수를 사용하여 표시 앞에 읽지 않은 OOB 데이터가 있는지 여부를 확인할 수 있습니다. 예를 들어 이 정보를 사용하여 데이터 스트림의 표시까지의 모든 데이터가 적절한 경우 삭제되도록 하여 피어와 다시 동기화할 수 있습니다.

SO_OOBINLINE 사용하지 않도록 설정된 경우(기본 설정):

  • Windows 소켓은 WSAAsyncSelect에 알림에 등록된 애플리케이션이 정상 데이터의 존재를 알리는 데 사용되는 것과 똑같은 방식으로 FD_READ 애플리케이션에 FD_OOB 이벤트를 알립니다. 즉, OOB 데이터가 이전에 큐에 대기되지 않은 상태에서 OOB 데이터가 도착하면 FD_OOB 게시됩니다. FD_OOB MSG_OOB 플래그를 사용하여 데이터를 읽을 때도 게시되지만 일부 OOB 데이터는 읽기 작업이 반환된 후에도 큐에 대기 상태로 유지됩니다. FD_READ 메시지는 OOB 데이터에 대해 게시되지 않습니다.
  • OOB 데이터가 소켓에 큐에 대기 중인 경우 적절한 exceptfds 소켓이 설정된 선택에서 Windows 소켓이 반환됩니다.
  • 애플리케이션은 언제든지 MSG_OOB 사용하여 recv 를 호출하여 긴급 데이터 블록을 읽을 수 있습니다. OOB 데이터 블록은 큐를 이동합니다.
  • 애플리케이션은 MSG_OOB 없이 recv 를 호출하여 일반 데이터 스트림을 읽을 수 있습니다. OOB 데이터 블록은 일반 데이터가 있는 데이터 스트림에 나타나지 않습니다. OOB 데이터가 recv를 호출한 후에도 유지되는 경우 Windows 소켓은 select를 사용할 때 FD_OOB 또는 exceptfds를 사용하여 애플리케이션에 알린다.
  • OOB 데이터가 일반 데이터 스트림 내에 위치가 있는 프로토콜의 경우 단일 사각형 작업이 해당 위치에 걸쳐 있지 않습니다. 한 사각형 은 표시 앞의 일반 데이터를 반환하고, 마크 뒤의 데이터 읽기를 시작하려면 두 번째 사각형 이 필요합니다.

SO_OOBINLINE 사용하도록 설정된 경우:

  • FD_OOB 메시지는 OOB 데이터에 대해 게시되지 않습니다. OOB 데이터는 selectWSAAsyncSelect 함수의 목적을 위해 정상적으로 처리되며, 소켓을 readfds 로 설정하거나 각각 FD_READ 메시지를 전송하여 표시됩니다.
  • 애플리케이션은 OOB 데이터 블록을 읽기 위해 설정된 MSG_OOB 플래그를 사용하여 recv 를 호출할 수 없습니다. 오류 코드 WSAEINVAL이 반환됩니다.
  • 애플리케이션은 MSG_OOB 플래그 집합 없이 recv 를 호출할 수 있습니다. 모든 OOB 데이터는 일반 데이터 스트림 내에서 올바른 순서로 전달됩니다. OOB 데이터는 일반 데이터와 혼합되지 않습니다. OOB 데이터를 지나가려면 세 가지 읽기 요청이 있어야 합니다. 첫 번째는 OOB 데이터 블록 이전의 일반 데이터를 반환하고, 두 번째는 OOB 데이터를 반환하고, 세 번째는 OOB 데이터 다음에 일반 데이터를 반환합니다. 즉, OOB 데이터 블록 경계가 유지됩니다.

WSAAsyncSelect 루틴은 SO_OOBINLINE 꺼져 있을 때 대역 외 데이터의 존재 알림을 처리하는 데 특히 적합합니다.

TCP의 OOB 데이터

중요

TCP 긴급 데이터를 사용하여 구현된 OOB(대역 외 데이터)에 대한 다음 설명은 버클리 소프트웨어 배포에 사용되는 모델을 따릅니다. 사용자 및 구현자는 다음 사항을 알고 있어야 합니다.

 

  • 현재 RFC 793 (개념이 도입된 위치)의 두 가지 상반되는 해석이 있습니다.

  • BSD(버클리 소프트웨어 배포)에서 OOB 데이터를 구현하는 것은 RFC 1122에 지정된 호스트 요구 사항을 준수하지 않습니다.

    특히 BSD의 TCP 긴급 포인터는 긴급 데이터 바이트 뒤의 바이트를 가리키고 RFC 규격 TCP 긴급 포인터는 긴급 데이터 바이트를 가리킵니다. 결과적으로 애플리케이션이 BSD 호환 구현에서 RFC 1122와 호환되는 구현으로 긴급 데이터를 보내는 경우 수신기는 잘못된 긴급 데이터 바이트를 읽습니다(데이터 스트림의 올바른 바이트 다음에 있는 바이트를 긴급 데이터 바이트로 읽습니다).

    상호 운용성 문제를 최소화하기 위해 애플리케이션 작성자는 기존 서비스와 상호 운용해야 하는 경우가 아니면 OOB 데이터를 사용하지 않는 것이 좋습니다. Windows 소켓 공급업체는 제품이 구현하는 OOB 의미 체계(BSD 또는 RFC 1122)를 문서화해야 합니다.

URG(긴급) 플래그가 설정된 TCP 세그먼트의 도착은 TCP 데이터 스트림 내에 단일 OOB 데이터 바이트가 있음을 나타냅니다. OOB 데이터 블록의 크기는 1바이트입니다. 긴급 포인터는 OOB 데이터 블록의 위치를 나타내는 TCP 헤더의 현재 시퀀스 번호에서 양수 오프셋입니다(앞부분에서 설명한 대로 모호함). 따라서 아직 수신되지 않은 데이터를 가리킬 수 있습니다.

긴급 포인터가 가리키는 바이트를 포함하는 TCP 세그먼트가 도착할 때 SO_OOBINLINE 사용하지 않도록 설정되면(1바이트) OOB 데이터 블록(1바이트)이 데이터 스트림에서 제거되고 버퍼링됩니다. 후속 TCP 세그먼트가 긴급 플래그 집합(및 새 긴급 포인터)과 함께 도착하는 경우 현재 대기 중인 OOB 바이트는 새 OOB 데이터 블록으로 대체되므로 손실될 수 있습니다(버클리 소프트웨어 배포에서 발생함). 그러나 데이터 스트림에서는 대체되지 않습니다.

SO_OOBINLINE 사용하도록 설정하면 긴급 데이터가 데이터 스트림에 유지됩니다. 따라서 긴급 데이터를 포함하는 새 TCP 세그먼트가 도착하면 OOB 데이터 블록이 손실되지 않습니다. 기존 OOB 데이터 표시가 새 위치로 업데이트됩니다.

참고

SO_OOBINLINE 소켓 옵션이 설정되면 SIOCATMARK IOCTL은 항상 TRUE를 반환하고 OOB 데이터는 일반 데이터로 사용자에게 반환됩니다.