커널 소켓 구조와 TCP_DIAG


18

TCP를 사용하여 실시간 데이터 서버에 연결하는 소프트웨어를 작업 중이며 일부 연결이 끊어졌습니다. 내 생각 엔 클라이언트가 서버에서 오는 데이터를 충분히 빨리 읽지 못한다는 것입니다. 따라서 TCP 소켓을 모니터링하고 싶습니다. 이를 위해 "ss"도구를 찾았습니다.

이 도구를 사용하면 모든 소켓의 상태를 확인할 수 있습니다. 다음은 명령 출력의 예입니다. ss -inm 'src *:50000'

ESTAB      0      0             184.7.60.2:50000       184.92.35.104:1105
  mem:(r0,w0,f0,t0) sack rto:204 rtt:1.875/0.75 ato:40

내 질문은 : 메모리 부분은 무엇을 의미합니까? 도구의 소스 코드를 보면 데이터가 커널 구조 ( sockin sock.h) 에서 온 것으로 나타났습니다 . 보다 정확하게는 다음과 같은 분야에서 나옵니다.

r = sk->sk_rmem_alloc
w = sk->sk_wmem_queued;
f = sk->sk_forward_alloc;
t = sk->sk_wmem_alloc;

누군가 그들이 무엇을 의미하는지 알고 있습니까? 내 추측은 :

  • rmem_alloc : 인바운드 버퍼의 크기
  • wmem_alloc : 아웃 바운드 버퍼의 크기
  • sk_forward_alloc : ???
  • sk->sk_wmem_queued : ???

내 버퍼 크기는 다음과 같습니다.

net.ipv4.tcp_rmem = 4096        87380   174760
net.ipv4.tcp_wmem = 4096        16384   131072
net.ipv4.tcp_mem = 786432       1048576 1572864
net.core.rmem_default = 110592
net.core.wmem_default = 110592
net.core.rmem_max = 1048576
net.core.wmem_max = 131071

버퍼 크기 구성은 무엇입니까? 소켓 연결에서 수신 버퍼가 포화되는 것을 보십니까? 상대방이 EWOULDBLOCK에서 연결을 끊습니까?
Karlson

내 소켓 크기는 상당히 작지만 게시물을 업데이트했습니다. EWOULDBLOCK의 경우 말할 수 없습니다. 내 클라이언트가 JAVA에 있으며 서버와의 연결이 끊어 졌다고 말합니다. 서버는 C ++에 있으며 아무런 정보없이 연결을 끊었다 고 말합니다. 서버의 소스 코드가 없으므로 동작을 변경할 수 없습니다. 클라이언트가 몇 초 동안 만 지속되는 경우에도 클라이언트가 약간 오버로드되면 연결이 끊어진 것 같습니다.
Twister

서버에서 버퍼 크기 구성을 조정할 수 있습니까? 클라이언트에서 버퍼 크기를 볼 수 있습니까? 고객의 소스에 액세스 할 수 있습니까? netstat -apnc를 실행하여 버퍼 크기를 보셨습니까? 커널에서 버퍼 크기를 늘려서 어떻게되는지 보셨습니까?
Karlson

네, 그들은 이미 서버의 최대 값으로 설정되어 있습니다 (net.ipv4.tcp_ * 속성보다 클 수 없다고 생각합니다.)? 내가 왜 ss를 보았는지. 커널의 경우 서버에서 루트가 아니며 여기의 IT 팀은 매우 완고합니다. 값을 변경하도록 요청하기 전에 어떤 일이 발생하는지 확인해야합니다 ... 그리고 클라이언트 소스에 액세스 할 수 있으며 클라이언트에 대한 조사 결과 서버에서 연결이 끊 겼음을 확인합니다.
Twister

netstat -apnc는 Linux에서 총 송신 및 수신 큐 크기를 제공합니다. 서버가 버퍼를 사용 가능한 최대 값으로 설정하고 여전히 포화 상태 인 경우 OS 수준에서 더 높은 버퍼 설정이 필요할 수 있습니다
Karlson

답변:


7

sk_forward_alloc 소켓 할당량에서 현재 사용 가능한 총 메모리 인 정방향 할당 메모리입니다.

sk_wmem_queued 송신 큐에 대기 된 소켓 송신 버퍼에 의해 사용되고 아직 송신되지 않았거나 승인되지 않은 메모리의 양입니다.

TCP 메모리 관리에 대한 자세한 내용은 Linux에서 TCP / IP 아키텍처, 설계 및 구현의 9 장 을 참조하십시오. Sameer Seth, M. Ajaykumar Venkatesulu


이 정의가 sk_wmem_queued와 어떻게 다른지 이해하지 못합니다 sk_wmem_alloc. 조금 더 확장 할 수 있습니까? (답을 알고 있다면이 질문에 대한 답을 자유롭게 추가하십시오 : unix.stackexchange.com/questions/551444/… )
little-dude

1

ss 매뉴얼 페이지를 참조하십시오.

<fwd_alloc>
   The  memory allocated by the socket as cache, but not used for receiving/sending packet yet. If need memory to send/receive packet, the memory in this cache will be used before allocate additional memory.

<wmem_queued>
   The memory allocated for sending packet (which has not been sent to layer 3)

0

sk_wmem_queuedsk_wmem_alloc에 대해서는 동일한 질문을 했기 때문에 여기에 답변을 복사하겠습니다.

Linux 네트워크 스택에 기여하는 Eric Dumazet에게 이메일을 보냈는데 여기에 답이 있습니다.

sk_wmem_allocqdisc 계층 및 NIC TX 링 버퍼와 같이 전송 스택 큐에 대기 skb의 바이트 수를 추적합니다 .

아직 보내지 않은 (cwnd limit) TCP 쓰기 대기열에 1MB의 데이터 sk_wmem_queue가있는 경우 약 1MB이지만 sk_wmem_alloc약 0입니다.

이 세 가지 유형의 대기열 (소켓 버퍼, qdisc 대기열 및 장치 대기열)이 무엇인지 이해하는 데 도움이되는 매우 유용한 문서이 기사 입니다. 간단히 말해서, 소켓은 패킷을 qdisc 대기열로 직접 밀어 넣어 장치 대기열로 전달함으로써 시작됩니다. qdisc 큐가 가득 차면 소켓은 자체 쓰기 큐에서 데이터 버퍼링을 시작합니다.

네트워크 스택은 대기열에 직접 패킷을 넣거나 대기열이 가득 찬 경우 상위 계층 (예 : 소켓 버퍼)을 다시 밀어 넣습니다.

따라서 기본적으로 sk_wmem_queues소켓 버퍼 ( sock.sk_write_queue) sk_wmem_alloc가 사용하는 메모리이고 qdisc 및 장치 큐의 패킷이 사용하는 메모리입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.