WRITE 에 대한 의문점.. 아시나요..?
글쓴이: wnldirqhrdyd / 작성시간: 수, 2010/03/24 - 11:36오전
안녕하세요
예를 들어 1000바이트의 데이터를
100바이트씩 쪼개서 10번을 보낸다는 가정하에
for문을 사용하여 write를 할 경우에
실제로 클라이언트가 받는상태가
100바이트씩 10번이 아닌
예를 들어 500바이트씩 2번이라던지
250바이트씩 4번이라던지
아님 1000바이트를 한번에 온다던지..
이런 현상이 일어나는 이유가 무엇인지..
통신포트를 중간에서 체크한결과,
서버가 저렇게 보내는걸로 확인되었습니다
왜 서버는 write를 10번 했지만 실제로 클라이언트에게 보내는
데이터의 크기와 횟수가 조정이 되는걸까요?
Forums:
TCP통신을 말씀하시는건가요?
TCP에서는 패킷단위가 보장이 안되는게 정상입니다. 스트림 방식의 통신이니까요...
따로 패키타이징을 하시든지, UDP를 이용하시든지 하면 될듯 합니다.
--
This is for you new people. I have just one rule :
Everyone fights, no one quits. If you don't do your job, I'll shoot you myself. Do you get me?
--
안녕하세요
네 통신환경은 TCP입니다
서버가 1~100까지를 10번으로 쪼개서 보내면
클라이언트는 받는대로 출력을 하는거라고 친다면
클라이언트가 1~10, 11~20, .... 이런식으로 출력이 되야하는데..
1~100이거나, 1~70, 71~100 이거나..
이런현상입니다.
패킷단위가 보장이 안된다는 말씀이 이 현상을 말씀하시는건지요..?
MTU와 관계 있는거
MTU와 관계 있는거 아닐까요. 보낸다고 해서 항상 재깍재깍 도착하지는 않습니다.
일반적으로 통신을 할 경우에
보내는 쪽이 100바이트를 100번 보냈다고
받는 쪽에서 100바이트씩 100번 나누어서 오는 경우는 거의 없습니다.
OS도 절대 그렇게 설계가 안 되어 있으며 중간에 관여하는 여러 통신 장치들도 절대로 그러한 것들까지 고려하여 설계가 되어 있지 않습니다.
TCP건 UDP건 간에 안되는 것을 하려고 하는 것입니다.
어떤 분이 UDP로 하면 된다고 하셨는데 UDP는 TCP보다 신뢰성이 떨어지는 통신 방법입니다.
UDP는 MTU 단위로 가긴 가겠지만 중간에 MTU 하나가 통째로 없어진다면 어떻게 하실려고요??
받는 측에서 재전송 요청해야 할텐데요??
예 그거야 당연하지요
UDP에 신뢰도가 없다는것은 UDP가 무엇인지 아는 사람이라면 모두 다 알고있는 내용이기에 적지 않았을 뿐이지요. ^^
--
This is for you new people. I have just one rule :
Everyone fights, no one quits. If you don't do your job, I'll shoot you myself. Do you get me?
--
TCP 의 네이글
TCP 의 네이글 알고리즘에 의해서 그렇게 되는 것 아닌가요?
100바이트씩 10번을 보내라고 했는 데 500바이트씩 2번 왔다면, send 큐에 5번째 쓰기 전까지 상대방으로부터 ack 를 못 받고 있다가
5번째 쓰기 후에 ack 를 받아 send 큐에 있는 내용을 한 번에 보낸 것 같습니다.
와우 감사합니다!
덕분에 이유를 찾은거 같네요 ㅎ
감사합니다 ㅎ
노파심에...
Nagle algorithm은 그냥 보내는 단에서 "소량의 보낼 데이터가 있을 때 기다리지 말고 바로 보내라"라고 힌트를 주는 것뿐이지, 회선 상태, 중간 라우터, 보내거나 받는 서버의 로드 등등에 따라 한 패킷에 들어가는 양은 언제든지 바뀔 수 있습니다.
이를테면 10바이트씩 보낼 때 예전에는 10바이트씩 받을 확률이 0.1%였다면 지금은 99.9%가 되는 것입니다. 절대로 100% 보장 못합니다.
write 함수를 정확히 이해못하신것 같습니다.
write 1000 바이트 를 호출했다면 write 함수는 로컬의 tcp 버퍼(보낼려는 remote 가 아닌)에 1000바이트를 쓰려고 시도합니다. 공간이 충분하면 1000 바이트 다 write하고, 충분하지 못하면 write한만큼의 크기를 반환합니다. 그리고 tcp/ip 드라이버는 로컬의 tcp 버퍼에 있는 내용을 전송가능할때마다 전송하게 됩니다(tcp 버퍼는 논리적으로 소켓을 만들때마다 생긴다고 생각하시면 됩니다). 그리고 이 전송과정에서 MTU 등의 크기와 전송 알고리즘에 따라 수신측에서 받는 크기가 정해집니다.
핵심은 write 1000바이트 를 정상적으로 호출한 결과는 remote에 1000바이트를 전송한것이 아닌 로컬 tcp 버퍼에 1000바이트 를 write했음을 의미하는 것입니다. 그내용이 remote에 정상적으로 전송되는지 아닌지는 보장되지 않습니다.
댓글 달기