[질문]VC++에서 CAsyncSocket에서 Send Buffer 보다 큰 사이즈를
글쓴이: paraline / 작성시간: 월, 2004/11/22 - 10:52오후
궁금한게 있어서 devpia에 질문을 올렸었는데, 만족할만한 답변이 없어서 여기에도 올려봅니다.
혹시 질문 자체가 이해가 안되시면 답글 주시면 다시 올리겠습니다.
아래의 CAsyncSocket은 논블럭으로 동작합니다.
Quote:
Socket에서 Send 함수가 리턴하는 값은 실제로 전송된 값이 아니라, Socket의 Send Buffer에 write한 값이라고 알고있습니다.
그렇다면, 실제 Send Buffer보다 큰 값을 Send하려고 한다면, 리턴값은 Socket Send Buffer 사이즈 만큼이고 나머지는 나중에 Send Buffer가 비었을때, 다시 전송이 되어야 할것 같은데, 테스트 결과는 그렇지 않더군요. 테스트를 위해서, Remote Socket에서는 Receive를 하지 않았습니다.
GetSockOpt로 Send Buffer Size를 보니까, 8192로 나왔습니다.그런데,
int nSend = Send(buff, 8192 + 1000);
이렇게 해도 nSend 가 9192가 나오는군요.왜 그런지 언뜻 이해가 안갑니다.
Send 내부에서는 단순히 socket api 함수인 send()만 호출하던데, Send Buffer Size보다 큰 값이 Send 되었다고 리턴되는 이유를 모르겠네요.프로그래밍 자체의 문제는 없습니다만, 갑자기 궁금해져서 질문 올립니다. ^^
Forums:
설명을 위해 몇가지를 정의합니다.1) 통신 개체A : 송신 프
설명을 위해 몇가지를 정의합니다.
1) 통신 개체
A : 송신 프로그램
B : 송신측 운영체제
C : 수신측 운영체제
D : 수신 프로그램
2) 통신유형
2-1) A->B : 송신프로그램에서 송신측 운영체제로 전송(MFC send())
2-2) B->C : 송신 프로그램과 관계없이 양단간의 운영체제끼리의 통신
2-3) C->D : 원격지 운영체제와 원격지 수신프로그램간의 통신
* 질문자의 오류
if ( D가 수신안하면 ) {
2-2 즉, B->C도 동작안할 것으로 오해함;
}
* 참고
B->C는 C의 수신버퍼가 찰때까지 동작합니다.
* 원하는 테스트를 하려면?
1) 원격지 버퍼를 가득 채울 만큼을 송신 : 이때 원격지 수신프로그램은 당근으로 recv()하면 안됨.단지 얼마나 수신되었나 검사하는정도라면 오케이!
2) 그후 송신자는 로컬송신버퍼의 크기만큼을 전송해본다. 만일 원격지
운영체제의 수신버퍼가 full이라면 질문에서 예측했던 값이 리턴될 것임.
3) 로컬 커널 송신버퍼 + 원격지 커널 수신버퍼 <=== 잘 ~ 생각해본다.
부연해서 설명하자면,송신자 : 철이송신운영체제 : 철이네 동네 우
부연해서 설명하자면,
송신자 : 철이
송신운영체제 : 철이네 동네 우체국
수신운영체제 : 영이네 동네 우체국
수신자 : 영이
영이가 안받으려고 해도, 철이가 일단 동네 우체국에
편지 넣으면, 영이네 동네까지는, 철이가 뭐라고 하건
영이가 뭐라고 하건간에 간다! 도로가 끊기거나, 천재지변이
없다면 말이다.
먼저 답변에 감사드립니다.[quote]* 질문자의 오류 if (
먼저 답변에 감사드립니다.
제가 오해할만하게 질문을 드렸군요. ^^
실제로 제가 테스트 했던건 1000000정도의 사이즈였습니다.
당연히 수신측에서는 Receive()를 안해줬고요.
그런데, GetSockOpt로 검사해보니, 송신측 send buffer와 수신측 recv buffer의 크기가 8KB였습니다.
그렇다면, 분명히 송신측 send buffer와 수신측 recv buffer가 꽉 차게되서 몇번에 나누어서 send가 되던가, 아니면, wouldblock이 리턴되어야 할것 같은데, Send() 한번에 1000000이 바로 리턴되는군요. ^^
좌절금지!!!
피할수 없다면 즐겨라.
사용자에게 보이는 소켓버퍼말고도 구현에 따라 내부적으로 버퍼가 있을 수
사용자에게 보이는 소켓버퍼말고도 구현에 따라 내부적으로 버퍼가 있을 수 있습니다. 윈도우의 경우 (문서가 기억이...) 분명히 내부적으로 소켓 버퍼를 따로 가지고 있습니다. 그 문서에는 윈도우 같은 경우 보내기 소켓 버퍼를 0으로 하고 비동기 Overlapped I/O 를 잘 사용하면 Zero Copy 전송을 구현할 수 있고 고성능의 보내기를 수행할 수 있다고 합니다. 하지만, 읽기 동작은 이렇게 해서는 소용없고 오히려 내부 버퍼를 더 키우는 결과를 가져온다고 읽었던 기억이 있습니다. 물론 FreeBSD 도 메모리를 잘 맞추면 이를 이용해서 이런 상황을 만들 수 있습니다.
하여간, 소켓 버퍼가 얼마인가를 신경쓰시는 것보다는 덜 보낸 경우 다시 보내는 부분만 (잘하고 계신다니) 잘 해주시면 될 것 같습니다.
[quote]윈도우의 경우 (문서가 기억이...) 분명히 내부적으로 소켓
아, 그렇군요.
이렇게 생각하니까 말이 되네요.
답변 정말 감사합니다.
막힌 속이 뻥 뚫렸습니다. ^^
좌절금지!!!
피할수 없다면 즐겨라.
댓글 달기