IP 계층에서의 커널버퍼 : /proc/sys/net/core
= 이건 주로 커널 소스나 설명에서 _SK_WMEM(송신)/_SK_RMEM(수신) 같은 용어/변수로 표현됩니다.
IPV4 전송계층에서의 커널버퍼 : /proc/sys/net/ipv4
= 이건 tcp_wmem(송신)/tcp_rmem(수신) 으로 표현됩니다.
불확실한 참고사항
장치드라이버가 DMA 에서 커널로 데이타를 복사할 때 커널버퍼 1블락을 잡아먹습니다.이걸 링버퍼라 합니다.
이건 대문자로 _SK_MEM 어쩌구 접두사를 달고 시작합니다.
흔히 skb 라 할 때 IPV4 또는 IPV6 만을 가정하고 표현하는 것인데 엄밀히 말하면 장치를 넘어온 패킷은 쓰레기일 수도 있고 EtherType 값이 저 두가지가 아니어서 다른 드라이버(예를들어 SAN 스토리지 모듈)로 가거나 아니면 폐기되는 것도 있기에 이런 것들도 엄밀히 말해 링버퍼 한블럭을 잡아먹는데 IPV4 API 로 이를 확인할 수 있는가는 잘 모르겠습니다.
무슨 이유로 이런 패킷이 잔뜩 들어오면 메모리와 시스템이 놀고 있어도 커널 링버퍼 풀로 넷트웍 자체가 안될 수도 있죠
skb 는 EtherType 값이 IP 일 때 이제 전송계층으로 넘어가든가 무슨 다른 이유로 IP 계층에서 드랍/처리되어야 합니다. 전송계층으로 넘어가면 sock 구조체(정확한 것은 확인하십시요)가 생성되고 이게 skb 블럭을 포인터합니다.
이 과정까지가 되고 TCP 일 때 비로소 tcp_*mem 관련 값이 적용받습니다. ICMP 는 커널계층에서 처리/드랍 되는 것이므로 끝나면 skb 해제되고 커널백로그도 -1 됩니다. UDP 역시 skb를 차지하지만 UDP만을 위한 설정은 못봤습니다. 아마도 처리가 TCP가 훨씬 복잡하고 더구나 ACK를 받지 못한 경우 타임아웃까지 버퍼를 유지하고 있어야 하므로(TCP백로그 카운트) 커널 메모리를 쓸데없이 잡아먹고 있을 우려가 있어서가 아닐까 생각합니다.
저도 확실한 답은 모르지만... ㅡ_ㅡ;;
답과는 상관 없는 내용도 적어 봅니다. ㅇ_ㅇ;;
오늘까지 이것저것 주워들은걸로. 배운 대로라면.. 이런겁니다.
1. 소켓 버퍼대신. 메모리 버퍼를 고정해서 사용하면.
소켓 생성 해지시의 메모리 생성 해지 시간이 단축되서 빨라진다.
쓰레드 풀' 메모리 풀'같은 경우가 그럴거 같습니다.
2. 소켓 버퍼 키우지 말고 비동기로 IOCP사용해서 메모리 버퍼 사용하면.
빠른것 처럼 보인다인거 같습니다.
3. 그런데. 실제로는 생성 해지 자체를 하지 않고. 고정으로 만들고 사용하면. 가장 빠릅니다.
그냥. 컴퓨터 100대 놓고. 1:1로 송수신하면 가장 빠르겠죠. ㅡ_ㅡ;;
4. udp readv writev 등을 응용하는것도 좋은 방법이라고 합니다.
윈도우는 WSARecv WSASend 같은 함수가 있을겁니다.
큐를 순차적으로 옮기느냐. 모인 수만큼 상자대로 옮기느냐.도 이에 포함될겁니다.
그렇지만. 빠르다고 반드시 좋지만도 않습니다.
하드웨어 수명도 문제가 되고. 화제 및 고장. 독성으로 인한 피해를 입는건 사람이니까요. ㅇ_ㅇ;;
점유율은 되도록. 80%를 넘지 않도록 하라는 당부에 말씀이 어디선가 들리는군요. ㅡ_ㅡ;;
오라클 데이가 눈에 띄네요... ㅡ_ㅡ;;
리눅스 소켓 버퍼
http://blog.naver.com/PostView.nhn?blogId=somet2001&logNo=50169142806
http://www.google.co.kr/images?newwindow=1&hl=ko&gbv=2&q=%EB%A6%AC%EB%88%85%EC%8A%A4+%EC%86%8C%EC%BC%93+%EB%B2%84%ED%8D%BC&revid=662532394&sa=X&oi=image_result_group&ei=4vRDUo7JJMfzlAXujIGoBA&ved=0CC0QsAQ
http://stackoverflow.com/questions/15706949/linux-socket-recv-buffer-packet-drops-even-for-pktcount-pktsize-so-rcvbuf
http://xenostudy.tistory.com/177
http://blog.naver.com/PostView.nhn?blogId=imageyes&logNo=20134359934
http://sumanaki.tistory.com/123
http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Network_Programing/Documents/SocketAPI
http://blog.daum.net/msgmap/15698210
http://okjazz.blog.me/90088358212
http://www.joinc.co.kr/modules/moniwiki/wiki.php/Site/Network_Programing/AdvancedComm/Window_size
http://blog.daum.net/danuplus/71
http://vaio04.egloos.com/913654
http://blog.daum.net/msgmap/15698210
http://blog.naver.com/imageyes?Redirect=Log&logNo=20134359934
윈도우 소켓 버퍼
http://blog.daum.net/kr_girls/8451078
http://blog.naver.com/buga0205?Redirect=Log&logNo=10174649948
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=5284&ref=1607
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=2925&ref=953
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=6107&ref=6077
메모리
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=7623&ref=7623
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNo=20&no=6510&ref=6491
오라클 데이
http://events.oracle.com/search/search?group=Events&keyword=
궁금한 사람
http://kldp.org/node/93804
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
버퍼의 크기를 알아내려면 getsockopt(...
버퍼의 크기를 알아내려면 getsockopt(... , SO_RCVBUF, ...)를 쓰시면 됩니다.
예제가 http://promisej7.tistory.com/4 에 있네요.
버퍼 사용량에 대해서는 비슷한 질문과 답변이 있었으니 참고하시기 바랍니다.
ioctl(..., FIONREAD, ...)를 호출하는 식입니다.
SO_RCVBUF 대신 SO_SNDBUF를 쓰고 FIONREAD 대신 FIONWRITE를 쓰면
소켓의 쓰기 버퍼에 대해서도 적용 가능하겠군요.
http://stackoverflow.com/ques
http://stackoverflow.com/questions/6989579/what-is-netbsds-fionspace-ioctl-equivalent-in-linux
Linux에서는 FIONREAD만 있고 FIONWRITE 라는 이름은 쓰지 않는 모양입니다.
위 글을 보니 SIOCOUTQ 라는 이름으로 지원된다고 하고요.
CentOS-5.10에서 찾아보니, /usr/include/linux/sockios.h 에 아래의 매크로 정의가 있고,
/usr/include/asm-x86_64/ioctls.h 에 아래와 같이 나옵니다.
정리해보면 Linux에서는 아래과 같은 셈이네요.
- SIOCINQ == TIOCINQ == FIONREAD
- SIOCOUTQ == TIOCOUTQ ( == FIONWRITE, but not defined)
리눅스가 없어서 요즘 정확한가 모르겠는데 커널내 각
리눅스가 없어서 요즘 정확한가 모르겠는데 커널내 각 수치(설정값)위치는
IP 계층에서의 커널버퍼 : /proc/sys/net/core
= 이건 주로 커널 소스나 설명에서 _SK_WMEM(송신)/_SK_RMEM(수신) 같은 용어/변수로 표현됩니다.
IPV4 전송계층에서의 커널버퍼 : /proc/sys/net/ipv4
= 이건 tcp_wmem(송신)/tcp_rmem(수신) 으로 표현됩니다.
불확실한 참고사항
장치드라이버가 DMA 에서 커널로 데이타를 복사할 때 커널버퍼 1블락을 잡아먹습니다.이걸 링버퍼라 합니다.
이건 대문자로 _SK_MEM 어쩌구 접두사를 달고 시작합니다.
흔히 skb 라 할 때 IPV4 또는 IPV6 만을 가정하고 표현하는 것인데 엄밀히 말하면 장치를 넘어온 패킷은 쓰레기일 수도 있고 EtherType 값이 저 두가지가 아니어서 다른 드라이버(예를들어 SAN 스토리지 모듈)로 가거나 아니면 폐기되는 것도 있기에 이런 것들도 엄밀히 말해 링버퍼 한블럭을 잡아먹는데 IPV4 API 로 이를 확인할 수 있는가는 잘 모르겠습니다.
무슨 이유로 이런 패킷이 잔뜩 들어오면 메모리와 시스템이 놀고 있어도 커널 링버퍼 풀로 넷트웍 자체가 안될 수도 있죠
skb 는 EtherType 값이 IP 일 때 이제 전송계층으로 넘어가든가 무슨 다른 이유로 IP 계층에서 드랍/처리되어야 합니다. 전송계층으로 넘어가면 sock 구조체(정확한 것은 확인하십시요)가 생성되고 이게 skb 블럭을 포인터합니다.
이 과정까지가 되고 TCP 일 때 비로소 tcp_*mem 관련 값이 적용받습니다. ICMP 는 커널계층에서 처리/드랍 되는 것이므로 끝나면 skb 해제되고 커널백로그도 -1 됩니다. UDP 역시 skb를 차지하지만 UDP만을 위한 설정은 못봤습니다. 아마도 처리가 TCP가 훨씬 복잡하고 더구나 ACK를 받지 못한 경우 타임아웃까지 버퍼를 유지하고 있어야 하므로(TCP백로그 카운트) 커널 메모리를 쓸데없이 잡아먹고 있을 우려가 있어서가 아닐까 생각합니다.
netstat을 이용하는건 틀린 방법인가요?
필요한 정보를 찾기위해 들렀는데...
netstat의 정보중에 RECV-Q,SEND-Q가 있지않습니까?
제가 알기로는 현재 사용하고있는 수신버퍼와 송신버퍼로 알고있는데
이게 현재 사용중인 버퍼사이즈가 아닐런지요..?
그 값은 금방금방 변해서 확인이 어렵겠지만... 메시지가 안보내진다거나 할때 확인해볼 수 있지않을까요?
그리고 궁금한게 한가지 있는데
getsockopt함수로 버퍼의 크기를 알아낼 수 있는데, 이 값과 netstat의 값이 다른건 왜 일까요?
현재 서버와 클라이언트를 연결하는 간단한 소켓프로그래밍을 작성하고, 클라이언트는 while(1)로 연결이 끊어지지 않는
상태를 유지하고 있습니다. 서버에서는 일정한 크기의 데이터를 계속 보내는 중이구요
한마디로 클라이언트에서는 recv를 하지 않는데 서버에서 send만 하고있는 상황입니다
netstat명령어로 확인해보니 클라이언트의 recv-q는 약 90만, 서버의 send-q는 약 250만정도의 수치를 나타내고 있습니다.(단위가 바이트인가요??)
근데 이 큐의 값과 getsockopt에서 확인한 값이 다릅니다.
둘다 버퍼의 값이기 때문에 같을거라 생각했는데 뭐 예를들어 해당 소켓이 사용하는 최대치가 따로 있는건지..
아니면 아예 이렇게 하는게 틀린건지 모르겠네요 ㅜㅜ
댓글 달기