2011-08-21 7 views
1

8 초마다 서버로 패킷을 보내는 클라이언트가 있습니다. 서버가 패킷을 너무 빨리 보내면 클라이언트 연결이 끊어지는 것을 감지합니다. 클라이언트에서는 Sleep (8000)을 호출합니다. 패킷을 보내기 전에 서버 측에서는 GetTickCount()를 사용합니다. 패킷 간의 시간을 계산합니다. 나는 이것이 문제없이 작동 할 것으로 기대했지만 계속 연결이 끊어졌습니다. 패킷 타이밍 문제

나는 패킷 시간을 확인하기 위해 WireShark로 사용하고 이것이 내가 가진 무엇 : 패킷 # 시간을 17 8.656064 (72) 16.957240 (115) 24.764741

24.764741-16.957240 = 7.807501 < 8 내가 연결있어 이유입니다 . 클라이언트에서 Sleep (8000)을 호출하기 때문에 이것을 이해할 수 없습니다. 8 초마다 패킷을 보내야합니다.

두 번째 패킷은 0.3 초 ​​늦었고 세 번째 패킷은 약 0.2 초 일찍 나타납니다. 시간 내에 이러한 패킷을 보내는 방법이 있습니까?

+2

한 마디로, 아니요. 이것은 완전히 비 결정적인 시스템입니다. 경로에 구성 요소 (및 로트가 있음)에 의한 확실한 보증이있을 수 없습니다. 퍼지 요소를 추가해야합니다. – Nim

답변

1

문제는 실제로 오래된 것입니다. 있는 TickCount 같은 컴퓨터에서도 여러 CPU 사이에 다릅니다

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/22c68353-1dbb-4718-a8d2-0679fdc0c298/

나의 제안은, 더 후 8000에 절전 모드 설정 9500 말을하고있는 TickCount에 대해 동일한 정비사를 유지한다, 그러므로 수면 항상 높아야한다.

읽을 수있는 또 다른 링크

은 여기에 있습니다 : 마이크로 소프트 Windows의 단락 특정 참조

http://en.wikipedia.org/wiki/Latency_(engineering)#Computer_hardware_and_operating_system_latency

.

업데이트 :

나는 이것이을 downvoted지고 이유는 모르겠지만 내가보기 나를 여기에, 문제를 명확하게 할 수 있습니다.

TickCount는 시간의 특정 척도로 의존 할 수 없으며, 하나의 처리 단위로 지역화 된 경우가 아닙니다. MSDN에 대한 첫 번째 링크는 이유에 대한 인용문을 제공합니다.

두 번째로, Windows 자체 의 타이머 논리가 정확하지 않습니다.

마지막으로, 크리스탈 자체의 타이머는 대기 조건이 압전 진동에 영향을주는 것으로 알려져 있기 때문에 다를 수 있습니다. 요약

http://en.wikipedia.org/wiki/Crystal_oscillator#Temperature_effects

이있는 TickCount는 신뢰할 수 있고 네트워크를 통해 패킷을 전송 절대 정밀도를 얻기 소비자 수준의 네트워크를 통해 달성하기 어려운 일이 아니다.

나의 해결책은 잠자기 타이머가 더 길게 기다린 후 틱 타이머가 우아하지 않지만 문제를 해결할만큼 '퍼지'로 충분하다는 것입니다.

패킷이 X 초 내에 도착한다고 보장 할 수는 없지만, 일 수 있습니다. 특정 기간이 지나기 전에 패킷이 전송되지 않을 것입니다.

+0

Downvoter는 관심이 있으십니까? –

+0

+1 Windows 타이밍은 결코 정확하지 않지만 틱 랩을 고려하면 멀티미디어 타이머 또는 다양한 대기 API를 사용하는 것이 좋습니다. –

1

내게는 이것이 작동하기를 기대하는 것이 이상하게 보입니다. 예를 들어 지연이 발생해도 패킷이 함께 버퍼링되어 전송 될 수 있습니다. 네트워크 상태에 따라 순서가 맞지 않거나 임의로 지연 될 수 있습니다. 서버 측에서 처리 될 때 시간은 얼마나 걸립니까? 서버의 타이밍은 클라이언트의 타이밍에 대해서는 아무 것도 말하지 않습니다.

2

시계의 정확도에 너무 의존하지 말고 지연 시간의 원인을 알고 자하는 답변은 정확합니다.

그러나 200ms 밖에 있다는 사실은 내가 TCP를 사용하고 있으며 Nagle 알고리즘을 끄지 않았다고 추측합니다. 시간에 민감한 프로토콜의 경우 TCP_NODELAY가 켜지도록 소켓을 설정해야합니다.

나머지 모든 TCP 대기 시간 경고가 적용됩니다. 일이 언제 일어날 지 당신은 알지 못하고 당신은 당신의 프로토콜에서 그것을 처리 할 필요가 있습니다.

0

네트워크에서 전송되는 개별 패킷의 정확한 시간을 예상 할 수 없습니다. 마지막 두 개의 패킷 사이의 시간을 기준으로 연결 해제 조건을 설정하는 대신 마지막 40 초 동안 5 개 이상의 패킷을 수신 한 경우 연결을 끊는 등 더 긴 기간 동안 평균을 구하십시오.