python 에서의 UDP ... 혹 아시는 분 대답좀...
글쓴이: nunorock / 작성시간: 목, 2003/08/07 - 3:04오후
python에서 UDP로 네트웍 프로그램 중입니다.
그런데 황당한 경우를 만났군요.
서버는
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.bind(('',6270)
while 1:
data, addr = s.recvfrom(1024)
if data:
print data
이렇게 하구요
클라이언트에서
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
for cnt in range(100)
buff = str(cnt)
s.sendto(buff,('211.179.51.109',6270))
이렇게 해서 UDP data 100개를 보내면
서버에서 100개를 모두 못 받습니다.
60개정도 까지는 제대로 받다가 그뒤부터는 중간중간 5,6개씩 빼먹고 받습니다.
즉
0
1
2
...
60
61
65
69
70
73
77
79
81
82
89
93
96
97
이런식 으로 말입니다.
문제는 리눅스에서는 이런식으로 문제가 생기는데
똑같은 사양의 컴에서 윈도우용 파이썬에서 서버프로그램을 하면
100개를 하나도 빠짐없이 잘 받는다는 것입니다.
왜그럴까요? 터보리눅스와 한컴리눅스 모두 같이 문제더군요.
윈도우에서는 문제가 없는데..
혹 아시는 분 제발 답변좀 부탁드립니다.
Forums:
sendto 의 리턴값을 검사하세요..
sendto()는 전송한 바이트수를 리턴합니다.
리턴값을 검사해서 모두 전송될 때까지 전송해야합니다.
폐인, 노가다 그 끝은..?

sendto 이상없습니다.
모두 제대로 전송했구요.
윈도우 파이썬으로 보내면 모두 잘 받습니다.
Re: python 에서의 UDP ... 혹 아시는 분 대답좀...
udp는 unreliable한 프로토콜입니다. 중간에 데이터를 손실할 수 있습니다.
또한, 순서가 바뀔수도 있습니다. 이 경우에는 라우터를 다수개 거친다는 가정이 있지요. 즉, 멀리 보낼때 해당됩니다. 또한, 중복되게 데이터가 올수 있습니다. 라우터와 라우터사이에서 이런일의 원인을 제공합니다.
따라서, 데이터를 손실한 경우는 지극히 정상입니다. 윈도우에서 수행시 정상전달된 것은 윈도우가 좋아서가 절대로 아닙니다. 타이밍이 좋아서라고 보는게 맞습니다. 유닉스에서 보낼때, 매 sendto()호출할때 usleep()을 주어서 수백밀리초동안 쉬도록해보십시요. 그리고 전송을 해보세요. 아마도 모든 데이터가 정상적으로 수신될 가능성이 높습니다.
만일 데이터의 손실을 원치않는다면, udp를 신뢰성있게 하는 프로그램을 짜거나(스티븐스책에도 예제가 있음), 아니면 tcp를 사용하는 방법이 있습니다.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
맞습니다.윈도우에서는 로컬로 UDP를 쏘는 거라 다들어왔더군요.결
맞습니다.
윈도우에서는 로컬로 UDP를 쏘는 거라 다들어왔더군요.
결국 윈도우나 리눅스나 똑같았습니다. (당연한거...T T)
그런데 한가지 더 궁금한것이 있더군요.
저희 회사가 50K 전용선이라 항상 50은 보장이 되는 속도입니다.
100개의 데이타를 외부에서 UDP로 날리면 마찬가지로 50개정도 까지는 빠짐없이 잘 들어오고 다음부터는 손실되는 양이 많습니다.
그래서 동키를 띄우고 약 20정도를 동키에서 잡아 먹게하고 같은 테스트를 해봤더니 신기하게 100중 30정도만 제대로 도착하는 것이었습니다.
UDP의 성공률이 회선속도와 문제가 있더군요.
왜 그러죠??
고수님들의 설명 부탁드립니다.
[quote="nunorock"]맞습니다.저희 회사가 50K 전용선이
50Kbps라고 해도 50Kbps가 전면 보장되지는 않습니다. 혼자서, 하나의 컴퓨터에서, 하나의 프로그램만이 회선을 사용하는 것이 아니기때문입니다. 회선은 하나인데 다수개의 컴퓨터 및 응용프로그램이 회선을 공유해서 사용합니다.
일대다의 공유지요. 이때 사용되는 기술이 멀티플렛싱입니다.
멀티플렉싱방식은 다양한 방법이 있습니다.
음 얘기가 너무 길어지면 안되니, 요점만 말씀드리면, 회선을 공유하는 컴퓨터간에 전송하는 데이터가 충돌이 발생할 수 있습니다. 물리적으로 충돌이 일어나는 것이지요. 충돌이 일어나면 상위 프로토콜의 입장에서는 데이터의 손실로 나타나게됩니다. 그러면 100개중 몇몇개가 손실되기 시작하지요. 교통혼잡이라고 생각하시면 되겠지요. 그리고, 데이터의 전송은 한단계에서만 가는게 아니고 수십개의 라우터를 거쳐서 중계되어 전송됩니다. 그러면 충돌의 확률은 더욱 높아지고, 점점더 전송율은 떨어지게 되겠지요. 물리 매체에 따라 다르지만, 전송성공율은 아주 낮습니다. 여기까지가 IP라고 보면되고, 이 상단에 아주 간략한 프로토콜을 입혀놓은게 UDP입니다. UDP는 여전히 신뢰성있는 전송을 못합니다.
이러한 충돌 및 기타 사유로 손실된 데이터를 손실없이 정확하게 맞는 값으로 보내려면 어떻게 할까? 이런 고민이 필연적으로 발생합니다. 방법은 보내고 응답받으면 되겠지요. 소위 핸드쉐이킹을 적용한 프로토콜을 개발하는 방법입니다.
보내고 응답받는 부분에 시간을 재는것은 필수적이지요. 함흥차사가 될지. 아니면 늦게라도 응답이 올지. 또한 데이터의 순서보장등을 고려해야합니다. 이러한 것들을 잘~ 만든 것중에 하나가 TCP입니다. UDP는 IP의 아주자그마한 확장프로토콜정도로 보는게 옳습니다. 나름대로의 장점은 물론 가지고 있지요.
UDP를 신뢰성 있게 보내려면? 위에서 TCP가 하듯이 만들면 됩니다. 예제는 위에도 언급했지만 스티븐스책에 나옵니다. 물론 방법은 가장 단순한 방법이지만, 그래도 학습용으로는 좋습니다.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
댓글 달기