그래서 몇 가지 테스트를 수행했습니다. 내 결과에 따르면, 그들이 기반 OS 구현에 의존한다는 것은 분명합니다. 참고로 Fedora 커널을 가지고 테스트했습니다 : 2.6.35.10-74.fc14.x86_64
.
결론은 async_resolve()
당신이 deadline_timer
을 설정하지 않고 멀리 얻을 수있을 수있는 경우에만 것으로 보인다는 것이다. 합리적인 행동을 취하는 모든 다른 경우에는 실질적으로 필요합니다.
async_resolve()
는
async_resolve()
에 대한 호출은 5 초 간격 4 개 쿼리의 결과. 처리기는 요청 후 오류가
boost::asio::error::host_not_found
인 20 초 후에 호출되었습니다.
My resolver는 기본적으로 2 초 동안 5 초의 시간 초과 (resolv.h
)로 설정되어 있으므로 구성된 쿼리 수가 두 배로 보입니다. 동작은 options timeout
및 options attempts
을 /etc/resolv.conf
에 설정하여 수정할 수 있습니다. 모든 경우에 전송 된 쿼리의 수는 attempts
으로 설정되었고 핸들러는 이후에 host_not_found
오류와 함께 호출되었습니다.
테스트의 경우 단일 구성된 네임 서버가 블랙홀 라우트되었습니다. 블랙홀 라우팅 대상으로 async_connect()
를 호출
async_connect()
는 핸들러가 ~ 1백89초 후 오류
boost::asio::error::timed_out
으로 호출되는 결과.
스택이 초기 SYN 및 5 회 재전송을 보냈습니다. 첫 번째 재 시도는 3 초 후에 전송되고 재시도 시간 초과는 매번 두 배가됩니다 (3 + 6 + 12 + 24 + 48 + 96 = 189). 재시도 횟수가 변경 될 수 있어야한다
[재전송 타이머]는 SYN 세그먼트 5의 디폴트는 RFC 1122 (4.2.3.5)에 부합하도록 선택된다
% sysctl net.ipv4.tcp_syn_retries
net.ipv4.tcp_syn_retries = 5
적어도 의 세그먼트를세그먼트의 재전송을 위해 3 분 이상으로 설정하십시오. 애플리케이션은 연결을 닫을 수 있습니다 (즉, 개방 시도를 포기할 수 있음). 물론 더 빠릅니다.
3 분 = 180 초이지만 RFC는 상한을 지정하지는 않습니다. 구현이 영원히 재 시도하는 것을 막을 수있는 방법은 없습니다. 소켓의 송신 버퍼가 가득 아니었다으로
async_write()
는 한,이 핸들러는 항상 바로 불렀다.
내 테스트에서 TCP 연결을 설정하고 1 분 후에 async_write()
을 호출하는 타이머를 설정했습니다. 대상에 블랙홀 이후의 트래픽 다운 스트림 라우터를 설정
- : 연결이 설정하지만
async_write()
호출하기 전에 한 분 동안, 나는 신체 상해의 모든 종류를 시도했다.
- 대상의 스푸핑 된 RST로 응답하도록 다운 스트림 방화벽에서 세션을 지우는 중입니다.
- 상관없이 내가 무슨 짓을했는지
/etc/init.d/network stop
를 실행하지 내 이더넷
뽑기, 다음 async_write()
즉시 성공을보고 핸들러를 호출한다. 방화벽이 RST를 위장하는 경우 은, 바로 연결이 닫혔습니다,하지만 난 알 방법이 없다고 내가 (이 즉시 boost::asio::error::connection_reset
을보고 할 것)을 다음 작업을 시도 할 때까지. 다른 경우에는 17-18 분 후에 결과가 나올 때까지 연결이 열려 있고 오류를보고하지 않습니다. async_write()
의 최악은 호스트가 재전송 중이며 송신 버퍼가 가득 찬 경우입니다.버퍼가 가득 차면 async_write()
은 재전송 시간이 초과 될 때까지 처리기를 호출하지 않습니다. 15 재전송 리눅스 기본값 : 재전송 사이
% sysctl net.ipv4.tcp_retries2
net.ipv4.tcp_retries2 = 15
시간 각각 이후에 증가 (그리고 여러 요인에 기초 같은 특정 연결의 추정 왕복 시간으로) 그러나 이분에 클램프된다. 따라서 기본 15 번의 재전송과 최악의 경우 2 분의 시간 제한을 사용하면 async_write()
처리기를 호출하기위한 상한선은 30 분입니다. 호출 될 때 오류는 boost::asio::error::timed_out
으로 설정됩니다.
async_read()
이
는 한 연결이 설정 및 데이터가 수신되지로 핸들러를 호출해서는 안됩니다. 나는 그것을 시험 할 시간이 없었다.
내 자신의'deadline_timer'를 만드는 것에 전념해야했기 때문에 불필요한 것인지 매우 관심이있었습니다. – chrisaycock
+1 흥미로운 질문입니다. 나는 그 대답이 대체로 플랫폼에 달려 있다고 생각한다. 나는 당신이 리눅스에 관심이 있다고 가정하고 있는가? –