저는 단일 이더넷 프레임을 수신한 다음 정확히 1초 지연(그 사이에 일부 처리 포함) 후에 데이터를 다른 이더넷 프레임으로 보내는 시간에 민감한 네트워크 애플리케이션을 작성하고 있습니다.
하지만 특히 어려운 점은 내가 할 수 있는 능력도 필요하다는 것입니다.취소이 지연 간격 동안 다른 유형의 다른 메시지가 수신되면 패킷 전송을 계속합니다.
정확히 1초의 지연을 얻기 위해 커널의소켓 타임스탬프 기능이것과 결합시간 기반 패킷 전송. 이 두 가지 기능을 결합하면 애플리케이션을 사용자 공간에 유지하면서 전체 시스템을 실시간 프로세스 스케줄러에서 실행할 필요 없이 예측 가능하고 상당히 정확한 대기 시간을 생성할 수 있습니다.
특히 소켓을 생성하고 socket(AF_PACKET, SOCK_RAW, TEST_ETHERTYPE)
(실제 응용 프로그램은 IPv4를 처리하지만 지금은 테스트를 위해 다른 에테르 유형을 사용하고 있습니다) 패킷 도착 타임스탬프를 생성하고 지정된 전송을 허용하도록 소켓 옵션을 SO_TIMESTAMPNS
설정 합니다.SO_TXTIME
그런 다음 메인 루프에서 애플리케이션은 API를 사용하여 수신된 패킷 데이터와 함께 제어 메시지를 recvmsg
반환하고 SCM_TIMESTAMPNS
, 패킷을 패킷으로 처리하여 보낸 다음, API를 사용하여 포함된 타임스탬프와 함께 사용하기 위해 대기열에 넣습니다(이는 제어 메시지는 수신된 타임스탬프로부터 1초 후에 sendmsg
전송 .SCM_TXTIME
그러나 대기열에 추가된 패킷을 실제로 "회수"할 수 있는 방법은 없는 것 같습니다. 시간 기반 전송을 사용하더라도 패킷이 오랜 시간 동안 대기열에 있을 수 있습니다.
나는 내 애플리케이션에서 내 자신의 패킷 대기열을 구현한 다음 패킷이 만료에 매우 가까울 때만 커널을 사용하여 패킷을 예약할 수 있다는 것을 알고 있습니다. 어쨌든 이는 커널 대기열에 압력을 가하는 것을 피할 수도 있습니다. 구현 방법에 관계없이 지연이 끝나면 항상 0이 아닌 간격이 있으며 패킷이 전송되기 전에 취소된다는 보장은 없습니다.
하지만 그렇다면오직내 응용 프로그램의 자체 소프트웨어 대기열에서 패킷을 취소할 수 있다면 최악의 경우 취소 창은 더욱 비관적일 것입니다. 왜냐하면 마감일 전에 패킷이 대기열에 있는지 확인할 때 고려해야 할 일정 불일치가 더 많기 때문입니다. 일반적으로 여러 스레드는 소프트웨어 대기열의 서로 다른 끝에서 관리되어야 하며 이는 더욱 복잡해집니다.
간단히 말해서, 패킷이 커널 대기열에 추가된 후 시간 기반 전송을 위해 패킷의 일정을 취소할 수 있는 방법이 있습니까?