네트워크 패킷 타이밍 문제

익명 사용자의 이미지

A 기기에서 매 200ms 마다 udp 패킷을 보내는 프로그램이 돌고 있습니다.
해당 프로그램은 poll의 timeout을 설정해서 대기를 하다가 200ms 내에 응답이 오면 A 루틴을 실행하고 아니면 B 루틴을 실행합니다. 이렇게 계속 반영구적으로 동작합니다.
이때 와이어샤크로 A 기기의 wan link를 미러링해서 패킷을 잡아보면 간혹 패킷을 보내고 응답이 없어 B 루틴까지 실행하는 타임 갭이 100ms, 150ms 되는 경향이 있습니다. (200ms 타이밍을 맞추는게 중요합니다)

우선 poll과 timeout이 문제인가 해서 elapsed time을 뽑아보니 2ms 오차는 있어도 대략 200ms 마다 도는 것은 확인하였습니다. 그러면 이때 어떤 식으로 더 접근을 해볼수 있을까요?

관련 키워드라도 알려주시면 감사드리겠습니다.

작성자의 이미지

아 참고로 B 루틴도 udp 패킷을 보내는 루틴이라서 와이어샤크로 타임 갭을 확인했습니다.

swish95의 이미지

보내고 그걸 검사하는데 걸리는 시간까지 포함해서 200ms 인가요?
가급적이면 타이머는 별도의 프로세스로 작업하는게 에러의 소지를 줄일수 있을것 같습니다.

------------------------------------------------------------
ProgrammingHolic

익명 사용자의 이미지

네, udp 패킷보내고 timeout 대기 후, 응답없을시까지(poll timeout이 끝나는 시점)가 200ms로 맞춰져야 합니다.

해당 로직을 별도의 프로세스로 빼서 작업하기엔 리스크가 커서 힘들것 같고요, 이 현상이 10번에 1번? 아니면 나타나지 않을때도 있습니다. 또 하나 의심가는건 실제 0 time에 보내지만 커널이 효율적으로 처리하려고 큐 버퍼에 넣어뒀다가 0+100ms 시점에서 release 시켜서 wan link 미러링시에 100ms 타임 갭으로 보이는게 아닌가 싶은데, 이걸 증명할 방법이 딱히 떠오르지 않네요..

swish95의 이미지

전문가들이 답변해주시겠지만...

받는 쪽에서 그 시점을 로깅한다면 어디가 문제인지 알수 있겠네요

그리고 님이 원하는대로 OS 가 동작하지 않을수 있다는 사실은 항상 염두에 두셔야 합니다.
가령 네트워크가 일시적으로 중단되었을수도 있는데 그걸까지 알아서 해주지는 않을테니까요
10번중에 한번이라고 하지만 그정도면 안된다고 봐야 되지 싶네요

------------------------------------------------------------
ProgrammingHolic

작성자의 이미지

답변 감사합니다.

아 혹시 커널 큐 버퍼가 있든 없든 바로 device layer로 bypass 시키는 소켓 옵션이나 이런게 없으려나요.
이러면 좀 문제의 크기를 줄여나갈 수 있을것 같다는 생각이 드네요.

익명 사용자의 이미지

참고로 해당 프로세스가 raw socket 이용해서 ethernet layer까진 바로 넘어가니 tcp/ip layer 옵션은 신경쓰지 않아도 될 것 같네요.

ymir의 이미지

매 200ms 마다 udp 패킷을 보내고, 다음 전송 주기인 200ms 내에 응답이 도착하기를 기대하시는 건가요?
네트워크가 그렇게 상상한 것처럼 아름답게 동작하지 않습니다.

기기 성능이나 라우팅, 트래픽, 스위치 등 다양한 조건에 의해 지연(latency) 이 발생하고..
UDP 같은 경우는 운 나쁘면 중간에 패킷이 drop 될 수도 있습니다.

패킷이 언제 나가고 언제 들어올 지는 정확하게 예측하기 어렵다.
TCP 는 네트워크에 문제가 없다면 언젠가는 반드시 돌아온다.
UDP 도 대부분은 응답이 오겠지만, 운이 나쁘면 패킷이 사라질 수도 있다.

이 정도를 염두에 두시고 로직을 다시 정리하시는게 좋을 것 같네요.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

익명 사용자의 이미지

> 매 200ms 마다 udp 패킷을 보내고, 다음 전송 주기인 200ms 내에 응답이 도착하기를 기대하시는 건가요?
> 네트워크가 그렇게 상상한 것처럼 아름답게 동작하지 않습니다.

아뇨 응답이 있든 없든 상관은 없는데 보내고 A 또는 B 루틴을 실행하기 까지의 시간 갭이 200ms에 근접해야 합니다. 10ms 정도야 그러려니 넘기는데 100ms는 영 찝찝해서요.

ymir의 이미지

정리하자면, 패킷을 보내고 200ms timeout 후에 B 루틴이 실행 되어야 하는데..
실제로는 패킷을 보낸 이후 300~350 ms 쯤에 실행된다는 건가요?

어쨌든 목적은 매 200ms 마다 A 또는 B 가 실행되게 하는 거구요?

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

익명 사용자의 이미지

> 실제로는 패킷을 보낸 이후 300~350 ms 쯤에 실행된다는 건가요?
네, 제 경우는 100, 150ms이 되는데 어쨌든 결론은 말씀하신 타이밍이 안 맞다가 맞습니다.

> 어쨌든 목적은 매 200ms 마다 A 또는 B 가 실행되게 하는 거구요?
네, 맞습니다. 정확하게는 매 200ms마다 보내고 응답없을 시 B 루틴에 의해 다른 udp 패킷이 전송되고요. (이때 상대측에서 패킷을 잘 받았는지는 이번 이슈의 고려대상이 아닙니다)

와이어샤크로 확인해서 timestamp gap이 "보내고 응답없어서 B 루틴에 의한 다른 패킷이 전송"되기 까지 100ms가 나오는 경우가 생기는게 문제입니다.

ymir의 이미지

이건 좀 미묘한 문제 같군요..

코드들은 어느 정도 오차를 감안해도 대부분 원하는 타이밍에 실행되었을 가능성이 높고..
패킷이 실제로 나가는 타이밍이 문제인 것 같은데..
이건 어차피 커널에서 알아서 처리하는 데다..
CPU 나 트래픽과 같은 다양한 요소들 때문에 지연이 생길 수도 있기 때문에..
프로그램에서 기기에서 패킷이 나가는 타이밍까지 완벽하게 조절하기는 어렵습니다.

설령 뭔가 수를 써서 정확한 타이밍에 내보냈다고 하더라도..
그 타이밍에 맞춰서 정확한 시간 간격으로 상대방이 수신한다는 보장도 없구요.
상황이 이러한 데, 정확한 타이밍(그것도 밀리 타임)에 맞춰서 패킷을 보내는게..
과연 의미가 있을지 약간 의문이 듭니다.

어느 정도 오차를 감안해서 보정하거나, 오차 허용 범위를 좀 더 넓히는 것도..
옵션이 될 수 있을 것 같네요.

되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』

라스코니의 이미지

기기의 운영체재가 무엇인가요?
리눅스라면 나름 jitter가 크지 않은 OS이기 때문에 코드에서 찾아야 할 것 같습니다. 윈도우라면 그냥도 발생했을 수도 있고요.

리눅스라면 UDP send() 호출하기 전에 프로세스/쓰레드 동기화나 세마포 같은 것에 영향을 받지 않나 살펴 보세요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.