소켓 프로그래밍에서 SO_SNDBUF 및 SO_RCVBUF에 대해서 질문드립니다.
글쓴이: yanagm / 작성시간: 화, 2006/07/25 - 12:49오후
안녕하세요, 처음뵙겠습니다.
게시판이 바뀌고 나서 뭔가 어색하네요 ㅎ_ㅎㆀ
본론으로 들어가서...
[질문1]
위의 저 옵션들이 커널 내부의 버퍼 크기를 설정해주는 인자라고 알고 있는데요.
만약에 send(socket, buf, 16384); 라는 명령문이 있고, 커널 버퍼가 1024라고 가정한다면
send 명령문은 1024번씩 커널 버퍼에 데이터를 전송하고, 커널 버퍼는 1024씩 들어오는 데이터를
패킷으로 만들어서 IP 레이어로 전송하는게 맞나요?
그리고 다른 질문인데요.
[질문2]
TCP 윈도우 사이즈(또는 TCP 슬라이딩 윈도우)는 소켓에서 조절할 수 없나요?
[질문3]
또한 TCP 윈도우 사이즈와 SO_SNDBUF 및 SO_RCVBUF는 관련이 없는게 맞나요?
긴 글 읽어주셔서 감사합니다.
답변 부탁드립니다.
Forums:
[답변1] 버퍼 크기
[답변1]
버퍼 크기 설정 인자인건 맞습니다.
수신버퍼 사이즈와 IP 레이어 전송 사이즈 단위와는 관계 없습니다.
그냥 app 가 커널에게 데이터를 달라고 하지 않을 경우 커널에서 수신버퍼에 담고 있는 max size 입니다.
커널은 1바이트만 수신 되더라도 모든 네트워크 레이어의 작업을 합니다.
송신 부분은 블럭킹모드와 논블럭킹모드에 대해 좀 알아 보시면 도움이 될 듯 합니다.
실제 전송되는 패킷 사이즈에 영향을 주는 것은 MTU와 MSS(Max Segment Size)가 있습니다.
위 둘을 조사해 보세요.
MSS 와 함께 네이글 알고리즘도 알아보시면 좋고, delay ack 라는 것도 찾아보세요.
[답변2]
아마 윈도 사이즈는 우리가 임으로 셋팅하는게 불가능할 듯 합니다.
게데가 그 사이즈는 tcp 가 알아서 동적으로 적절하게 사이즈를 조절하도록 되어 있습니다.
속도제한을 위해 작게 만드는게 목적이 아니고, 최고의 효율을 위한 것이라면 그냥 원래 알고리즘대로 작동하도록 하는게 최상일 것으로 판단됩니다.
[답변3]
버퍼의 사이즈에 영향을 받는 것으로 알고 있습니다.
윈도우는 버퍼를 핸들링하기 때문에 버퍼보다는 커지지 않는 것으로 알고 있습니다.
...
[질문1]
쉽게 말해 "TCP Window Size=TCP버퍼크기"이며, 파일버퍼등의 fd버퍼와 같이 프로세스자원입니다.
read(),recv()등 BSD소켓함수는 TCP Windows Size에 절대적으로 의존합니다.
(MTU,MSS와는 상관없습니다. 그건 커널, 정확히는 디바이스드라이버자원이며 Raw socket제어시 Routing과정에서나 신경써야할부분입니다)
[질문2]
setsockopt()시스템콜로 조절합니다.
setsockopt(fd,SOL_SOCKET,SO_SNDBUF,(char*)&size,sizeof(size));
setsockopt(fd,SOL_SOCKET,SO_RCVBUF,(char*)&size,sizeof(size));
AIX4.3이상은 다른옵션이 존재합니다. (아마 AIX5L은 위 옵션이 먹을것같은데 확신할수없습니다)
setsockopt(fd,IPPROTO_TCP,TCP_RFC1323,(char*)&size,sizeof(size));
[질문3]
말씀드렸다시피 SO_SNDBUF,SO_RCVBUF로 TCP윈도우사이즈를 조절합니다.
구글검색하시면 첫페이지 첫번째에 http://www.ncsa.uiuc.edu/~vwelch/net_perf/tcp_windows.html가 나오는군요 :-)
homeless
답변 정말 감사드립니다~!
제가 영어가 짧아서, 그리고 한글로 된 소켓 책들이 이것들에 대해서
명시적으로 얘기를 하고 있지 않아서 여러 가지 생각이 많았는데,
이렇게 답변을 주셔서 감사합니다.
결국, 'TCP 윈도우 사이즈 = 커널에 의해서 생성되는 입력과 출력을 위한 기본 버퍼'라고 생각하면 되는거네요.
[추가 질문]
그렇다면... 사용하는 소켓이 블로킹 소켓일 때, send(), recv() 함수 호출시에 남아있는 'TCP 윈도우 사이즈' 만큼
application data가 TCP 윈도우 사이즈로 전송되며, 그것들이 모두 전송되기 전에는 블로킹되고 있는 것이 맞겠군요?
ps. Ethereal로 패킷 캡쳐해보니 실제로 그렇게 작동하네요. 감사합니다^^
댓글 달기