여러 소스의 멀티캐스트를 재조립하는 "좋은" 방법이 있습니까?
-
19-08-2019 - |
문제
저는 현재 Boost asio를 사용하여 우리를 위해 무거운 작업을 수행할 수 있도록 기존 독점 소켓 래퍼 코드를 재작업하고 있습니다.아마도 기존 코드에서 가장 복잡한 영역은 멀티캐스트 처리 코드일 것입니다.코드를 사용하면 중간 계층 서버(한 시스템에 여러 개가 있을 수 있음)가 멀티캐스트를 클라이언트 상자로 보낼 수 있으며, 클라이언트 상자는 이를 사용하여 시스템 사용자에게 업데이트를 제공합니다.
코드가 복잡하고 오류가 발생하기 쉬운 이유는 다수의 원시 버퍼를 사용하여 멀티캐스트 스트림의 출처에 따라 재조립하기 때문입니다.Boost.Asio를 사용하더라도 이 동일한 문제를 처리해야 할 것으로 보이므로 문제에 봉착하기 전에 다른 사람들이 이 상황을 어떻게 처리했는지 물어볼 가치가 있다고 생각했습니다.
매우 일반적인 사용 사례인 것 같습니다.현재 가지고 있는 코드 없이 이 작업을 수행하는 데 도움이 될 수 있는 것이 있나요?아니면 이런 종류의 작업을 수행할 수 있는 확립된 C++ 템플릿(Boost 또는 기타)이 있습니까?
분명히 작업을 더 쉽게 만들고 STL 컨테이너를 사용하여 원시 배열 대신 패킷을 버퍼링할 수 있지만 이 코드는 실제로 고성능이 필요합니다.대규모 설치에는 엄청난 수의 패킷이 날아다니므로 가능한 한 실시간에 가깝게 응답해야 합니다.
이 문제에 대한 의견을 보내주셔서 미리 감사드립니다.
제이미
해결책
자세한 답변을 위해 충분한 정보를 제공한 것 같지는 않지만 멀티캐스트 데이터의 실시간 처리를 위해 고려해야 할 몇 가지 일반적인 사항이 있습니다.
- 원시 UDP 멀티캐스트를 사용하는 경우 손실되거나 중복된 패킷을 처리하기 위해 사용자 공간에서 일종의 프로토콜 순서 지정을 수행하고 있을 것입니다.어떤 최적화를 원하든, 유혹에 저항하다 애플리케이션과 프로토콜 계층 사이의 계층화를 깨뜨립니다.
std::vector
, 는 대부분의 경우 동적 할당된 원시 문자 버퍼와 동일합니다.추상화 레이어라는 이유만으로 사용을 주저하지 마세요.그러나 이를 피해야 하는 두 가지 경우가 있습니다.- 정적으로 할당된 버퍼를 사용하여 벗어날 수 있는 경우
- 버퍼 다운스트림의 소유권을 이전해야 하는 경우(신중하게 설계하면
swap()
충분할 수도 있음)
- 사전 할당은 당신의 친구입니다.데이터가 들어올 때 사용할 수 있는 버퍼 세트가 있는 경우 빠른 실행 경로에서 대부분의 동적 할당을 제거할 수 있습니다.
- 메모리 복사본을 최소화합니다.단일 호출 스택에서 데이터를 처리할 수 있다면 복사를 피할 수 있는 기회가 있습니다.데이터를 다른 스레드로 전달해야 하는 경우 데이터를 강제로 복사해야 할 수도 있습니다.
- 애플리케이션이 청크 버퍼를 처리할 수 있는 경우(모든 데이터를 단일 버퍼로 집계하는 대신)
writev
그리고readv
.
나는 어떤 미리 준비된 해결책도 당신의 문제를 해결할 것이라고 믿지 않습니다.부스트 ASIO, libevent
, 등.모두 소켓 추상화를 처리하지만 데이터가 전달된 후에는 데이터로 수행하는 작업은 여전히 사용자의 책임입니다.