[질문] 네트워크 소켓에서 질문 있습니다
글쓴이: hados / 작성시간: 금, 2006/02/03 - 9:14오전
일을 하다가 문제점이 있어서 글을 올리니다.
네트워크를 통해서 UDP로 패킷을 받아서 파일로 저장을 하려고 합니다
프로그램은 뭐...매우 간단하죠. 보통 소켓 프로그래밍 예제 수준의
100줄 정도의 프로그램을 짜서, 패킷을 받아서 파일로 저장하도록
짰습니다.
그런데 가끔씩 data에 손실이 생깁니다.
sender에서 보낸 파일 크기와 receiver 쪽에서 받은 파일의 크기가
약간 차이가 날 때가 있습니다.
지금 생각으로는
sender에서 보낸 파일이 버퍼에 저장되고, receiver 프로그램이
이 버퍼에서 데이터를 읽어와서 파일로 저장하는데,
이 버퍼의 크기가 작고, sender 에서 보내는 속도와
receiver 쪽에서 data를 가져가는 속도에 차이가 나서
버퍼 오버플로우가 나서 거기서 데이타가 좀 손실되지 않나
생각하고 있습니다.
문제가 이것이라고 할 때,
socket을 열면서 setsockopt() 함수를 써서 소켓 버퍼를
늘려주는 방법을 썼었는데, 무작정 이 버퍼를 늘려주기만
하면 되는건가요?
소켓 버퍼를 한 100MB 로 잡아도 소켓 버퍼가 그만큼 잡힐 거
같지도 않고, 또 limit가 있다면 어디에 있는지,
아니면 아예 다른 방법으로 접근해야 하는지
감이 잘 안잡히네요
고수님들의 조언 바랍니다 :)
Forums:
파일전송에...UDP 쓰시면 피곤하실텐데요 ^^;
UDP는...out of order 입니다 -_-;
순서가 뒤죽박죽 올수있고...게다가 중간에 빠질수도 있습니다...
파일전송엔 지극히 좋지않습니다 :)
TCP로 쓰세요~ 아니면 UDP를 굳이 쓰시겠다면....
Reliable하게 Application Protocol을 다 정의해서 seq_num등을
부여해서 만드셔야 할겁니다.
------------------------------------------
Let`s Smart Move!!
http://kalstein.tistory.com/
udp는 사용자 영역이 아닌 커널(운영체제)에서 필요시(불가피시) 패켓을
udp는 사용자 영역이 아닌 커널(운영체제)에서 필요시(불가피시) 패켓을 버리기도 합니다. 사용자가 열심히 파라메터를 세팅하고 노력해도 신뢰성 있는 송수신을 보장받지 못한다는 얘기입니다.
다른 목적이 없다면, tcp를 사용하면 그런 문제가 없어지겠지만, 반드시 udp를 써서 파일전송등 신뢰성있는 데이터전송을 하고 싶다면, 신뢰성부분을 응용프로그램수준에서 구현해보는 방법(순서조정, 중복처리, 재전송, 타임아웃 등등)이 있습니다.
신뢰성, reliable, reliability , udp를 키워드로 kldp에서 검색해보시면 좋은 답변들이 다수개 있으리라고 봅니다.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
두 모듈이 통신한다고 할때받는쪽 모듈의 속도가 보내는쪽 보다 항상 빠
두 모듈이 통신한다고 할때
받는쪽 모듈의 속도가 보내는쪽 보다 항상 빠르다는 보장이 없으면
큐잉 버퍼를 늘려줘도 언젠가는 문제가 생깁니다.
queuing theory라는 간단한 수학 분야에서 증명이 된 내용입니다.
따라서 버퍼크기를 늘리는건 해답이 안되고
위엣분 말씀처럼 TCP를 이용하시던지,
udp를 이용해서 tcp처럼 만드시던지 해야 합니다.
tcp에는 기본적으로 받는쪽의 속도가 느릴 경우
보내는 쪽에 천천히 보내라고 하는 기능이 포함되어 있습니다. (flow control)
권위를 의심할 것,어긋남을 존경할 것,자리잡기를 거부할 것,항상 자신을 재창조할 것 - MIT 미디어랩 -
[quote]소켓 버퍼를 한 100MB 로 잡아도 소켓 버퍼가 그만큼
setsocketopt 로 100MB 를 잡으신 후, 다시 getsocketopt 로 확인하시면 얼마나 잡혔는지 아실 수 있겠죠..
근데 버퍼 늘려서 해결할 수 있는 문제는 아닌 것 같습니다.
유한이라는 점에서는 100MB 든 1G 든 버퍼에 쌓이는 속도가 더 빠르면 언젠가는 바닥 날테니까요.
flow control 기능이 있는 tcp 를 쓰시든지, udp 상에서 자체적으로 flow control 을 구현하시던지 해야할 듯.. (말하다 보니 윗분들이랑 같은 말이네요 헉..)
즐겁게 살아 볼까나~*
버퍼를 늘일수도 있지만 프로토콜 설계하실 때, 받는 쪽에서 offse
버퍼를 늘일수도 있지만
프로토콜 설계하실 때, 받는 쪽에서 offset을 보내면, 보내는쪽은 그 뒤로 계속 보낸다고 하고,
패킷하나 보낼때, offset, size, 마지막 패킷인지의 여부를 주어서 계속 전송하게 한다음,
받는 쪽에서 중간에 하나 빠지면 그 빠진 곳의 offset을 한번씩 보내면 될 것 같습니다.
---
http://coolengineer.com
답변 감사합니다. :)여러분의 답변이 다 비슷한것으로 보아
답변 감사합니다. :)
여러분의 답변이 다 비슷한것으로 보아
tcp를 쓰거나 프로토콜을 tcp처럼 만드는 것이 왕도인듯 합니다...만
제가 제 상황을 그리 많이 쓰지 않은 것이 문제군요. -_-;;;
현 상황에서 sender 쪽은 건드릴 수가 없습니다.
저는 sender 프로그램 등등을 받아서 일을 하는 상태여서
sender 쪽을 수정할 수도 없고, udp대신 tcp를 쓸 수도 없습니다.
이런 상황이므로 sender 를 만든 쪽과 협의해서
tcp를 쓴다거나 sender를 좀 수정한다거나 하는 식으로 해결하던지
아니면 현 상황에서 끝을 내야 겠네요 ㅠㅠ
답변 감사합니다 :)
댓글 달기