TCP 소켓 접속에 「킵 얼라이브」가 있습니까?
HTTP keep-alive는 들어본 적이 있지만, 지금은 리모트 서버와의 소켓 접속을 열고 싶습니다.
이 소켓 접속은 영원히 오픈 상태로 유지됩니까?아니면 HTTP 킵얼라이브와 마찬가지로 타임아웃 제한이 있습니까?
TCP 소켓 접속에 「킵 얼라이브」가 있습니까?
즉, TCP Keep-Alive를 통해 타임아웃이 적용되므로 소켓이 영원히 열려 있는 것은 아니지만 몇 시간 후에는 타임아웃이 될 수 있습니다.
머신의 킵얼라이브 타임 아웃을 설정하는 경우는, 다음의 「TCP 타임 아웃의 변경」섹션을 참조해 주세요.그렇지 않으면 나머지 답변을 읽고 TCP Keep-Alive 동작에 대해 알아보십시오.
서론
TCP 접속은 접속 양 끝에1개씩 2개의 소켓으로 구성됩니다.을 종료하고 는, 「」를 합니다.FIN
이치노
다만, 그 때까지, 양쪽 모두 소켓을 무기한 열어 둡니다.에 의해, 으로 또는 다른 한쪽의 소켓을 .이러한 경우는, 다른 한쪽이 다른 한쪽을 경유해 , 소켓을 통해 경우가 있습니다.FIN
이 시나리오를 검출하고 오래된 접속을 종료하기 위해서는 TCP 킵얼라이브 프로세스가 사용됩니다.
킵얼라이브 프로세스
Keep-Alives 작동 방식을 결정하는 세 가지 구성 가능한 속성이 있습니다.Linux 에서는 다음과1 같습니다.
tcp_keepalive_time
- 디폴트: 7200초
tcp_keepalive_probes
- 디폴트 9
tcp_keepalive_intvl
- 디폴트 75초
프로세스는 다음과 같이 동작합니다.
- 클라이언트가 TCP 연결을 엽니다.
- 일 경우
tcp_keepalive_time
의 빈 초를 합니다.「 」ACK
패킷.1 - 하는 「」로했습니까?
ACK
★★★★★★★★★★★★★★★★?- 아니요.
- 주세요.
tcp_keepalive_intvl
한 번 더 , 초를 더 보내고, 초를 한 번 더 보내 주세요.ACK
- '수'까지 반복하세요.
ACK
는, 「」와 같습니다.tcp_keepalive_probes
. - 는, 「」를 .
RST
접속을 종료합니다.
- 주세요.
- 예: 순서 2로 돌아갑니다.
- 아니요.
이 프로세스는 대부분의 운영체제시스템에서 디폴트로 이니블로 되어 있기 때문에 상대방이 2시간 11분(7200초+75*9초) 동안 응답하지 않으면 데드 TCP 접속이 정기적으로 플루닝 됩니다.
고차스
디폴트:
기본적으로 연결이 2시간 아이돌 상태가 될 때까지 프로세스가 시작되지 않기 때문에 오래된 TCP 연결은 플루닝되기 전에 매우 오랫동안 지속될 수 있습니다.이는 데이터베이스 연결과 같은 고가의 연결에 특히 해로울 수 있습니다.
Keep-Alive는 옵션입니다.
RFC 1122 4.2.3.6에 따르면 TCP 킵얼라이브 패킷에 대한 응답 및 릴레이는 옵션입니다.
실장자는 TCP 실장에 「킵얼라이브」를 포함할 수 있습니다만, 이 프랙티스는 일반적으로 받아들여지지 않습니다.킵얼라이브가 포함되어 있는 경우, 애플리케이션은 TCP 접속 마다 킵얼라이브를 on/off 할 수 있어야 하며, 디폴트에서는 off로 할 필요가 있습니다.
...
데이터가 포함되지 않은 ACK 세그먼트는 TCP에 의해 신뢰성 있게 전송되지 않는다는 것을 기억하는 것이 매우 중요합니다.
그 이유는 Keep-Alive 패킷에는 데이터가 포함되어 있지 않기 때문에 엄밀하게 필요하지 않기 때문에 과도하게 사용하면 인터웹의 튜브가 막힐 위험이 있기 때문입니다.
그러나 실제로는 대역폭이 저렴해짐에 따라 시간이 지남에 따라 이 우려가 줄어들기 때문에 Keep-Alive 패킷은 일반적으로 폐기되지 않습니다.예를 들어 Amazon EC2 문서에서는 Keep-Alive에 대한 간접적인 승인을 제공하고 있으므로 AWS를 사용하여 호스팅하는 경우 Keep-Alive에 의존해도 안전하지만 마일리지가 다를 수 있습니다.
TCP 타임아웃 변경
소켓 단위
도 TCP 에 Java는 TCP OS 등의 설정을 .java.net.Socket
Java Native Interface(JNI; Java 네이티브인터페이스)를 사용하여 이러한 옵션을 설정하기 위해 네이티브코드를 호출하는 Java 소켓을 작성하려는 시도는 몇 가지3 있었지만 커뮤니티에서 널리 채택되거나 지원되는 것은 없는 것 같습니다.
대신 운영 체제 전체에 구성을 적용해야 할 수 있습니다.이 설정은, 시스템 전체에서 실행되고 있는 모든 TCP 접속에 영향을 주는 것에 주의해 주세요.
리눅스
현재 설정되어 있는TCP 킵얼라이브 설정은, 다음의 URL 에 있습니다.
/proc/sys/net/ipv4/tcp_keepalive_time
/proc/sys/net/ipv4/tcp_keepalive_probes
/proc/sys/net/ipv4/tcp_keepalive_intvl
다음과 같이 업데이트할 수 있습니다.
# Send first Keep-Alive packet when a TCP socket has been idle for 3 minutes
$ echo 180 > /proc/sys/net/ipv4/tcp_keepalive_time
# Send three Keep-Alive probes...
$ echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes
# ... spaced 10 seconds apart.
$ echo 10 > /proc/sys/net/ipv4/tcp_keepalive_intvl
이러한 변경은 재시작을 통해 유지되지 않습니다.변경을 하려면 , 「」를 합니다.sysctl
:
sysctl -w net.ipv4.tcp_keepalive_time=180 net.ipv4.tcp_keepalive_probes=3 net.ipv4.tcp_keepalive_intvl=10
Mac OS X
되어 있는 은, 「이러다」, 「이러다」로 할 수 .sysctl
:
$ sysctl net.inet.tcp | grep -E "keepidle|keepintvl|keepcnt"
net.inet.tcp.keepidle: 7200000
net.inet.tcp.keepintvl: 75000
net.inet.tcp.keepcnt: 8
OS OS X가 정의되어 있습니다keepidle
★★★★★★★★★★★★★★★★★」keepintvl
위는는는는는는는는는는는는는는는 。
은 can음음음음음음음음음음음음음음 the the the the로 설정할 수 .sysctl
재기동 후에도, 다음의 설정이 유지됩니다.
sysctl -w net.inet.tcp.keepidle=180000 net.inet.tcp.keepcnt=3 net.inet.tcp.keepintvl=10000
'어느 쪽인가'에 도 있어요./etc/sysctl.conf
( ( ( ( ( ( ( ( 。
$ cat /etc/sysctl.conf
net.inet.tcp.keepidle=180000
net.inet.tcp.keepintvl=10000
net.inet.tcp.keepcnt=3
창문들
확인할 Windows 머신은 없지만, 다음의 레지스트리에서 각각의 TCP 킵얼라이브 설정을 찾을 수 있습니다.
\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP\Parameters
각주
을 참조해 주세요.man tcp
자세한 정보는.
2.이은, 「킵 얼라이브」패킷이라고 경우가 만, 에서는, 의 2 에 지나지 않습니다.「킵 얼라이브」라고 하는 것은, 「킵 얼라이브」라고 하는 TCP 입니다.ACK
상의 및 으로써 "을 붙일 수 .Wireshark와 같은 애플리케이션은 소켓 상의 이전 통신을 참조하여 포함된 시퀀스 및 확인 응답 번호를 메타 분석함으로써 "Keep-Alive" 패킷으로 라벨을 붙일 수 있습니다.
3. 기본적인 구글 검색에서 찾은 예로는 lucwilliams/JavaLinuxNet과 flonatel/libdontdie가 있습니다.
TCP 소켓은 닫을 때까지 열려 있습니다.
단, 실제로 데이터를 송신하지 않고 끊어진 접속을 검출하는 것은 매우 어렵기 때문에 대부분의 어플리케이션은 접속이 실제로 활성화되어 있는지 확인하기 위해 ping/pong 반응을 자주 합니다.
SO_KEEPALIVE 소켓옵션을 찾고 있습니다.
Java Socket API는 킵얼라이브를 통해setKeepAlive
★★★★★★★★★★★★★★★★★」getKeepAlive
★★★★★★★★★★★★★★★★★★.
편집: SO_KEEPALIVE는 "실제" 데이터를 전송하지 않고 OS 네트워크 프로토콜 스택에 구현됩니다.keep-alive 간격은 운영 체제에 따라 다르며 커널 매개 변수를 통해 조정할 수 있습니다.
데이터가 송신되지 않기 때문에 SO_KEEPALIVE는 네트워크 접속의 유효기간만 테스트할 수 있으며 소켓이 접속되어 있는 서비스의 유효기간은 테스트할 수 없습니다.후자를 테스트하려면 서버에 메시지를 보내고 응답을 받는 작업을 구현해야 합니다.
TCP 킵얼라이브와 HTTP 킵얼라이브는 매우 다른 개념입니다.TCP 킵얼라이브는 오래된 접속을 검출하기 위해 송신되는 관리 패킷입니다.HTTP에서 keepalive는 영속적인 접속 상태를 의미합니다.
이것은 TCP 사양의 것입니다.
킵얼라이브 패킷은 일정 시간 내에 접속에 대한 데이터 또는 확인 응답 패킷이 수신되지 않은 경우에만 전송해야 합니다.이 간격은 설정 가능해야 하며 기본값은 2시간 이상이어야 합니다.
보시다시피 대부분의 응용 프로그램에서 기본 TCP 킵얼라이브 간격이 너무 깁니다.응용 프로그램 프로토콜에 keepalive를 추가해야 할 수 있습니다.
오늘날 대부분의 홈 사용자가 그렇듯이 위장 NAT을 사용하는 경우 외부 포트의 풀이 제한되어 있으며 이러한 포트는 TCP 연결 간에 공유되어야 합니다.따라서 NAT을 가장하는 것은 특정 기간 동안 데이터가 전송되지 않은 경우 연결이 종료되었다고 가정하는 경향이 있습니다.
이 문제 및 기타 문제(두 엔드포인트 사이의 모든 부분)는 합리적인 유휴 기간이 지난 후 데이터를 전송하려고 하면 연결이 더 이상 "작동"되지 않음을 의미할 수 있습니다.그러나 데이터를 전송하기 전에는 이 정보를 찾을 수 없습니다.
킵얼라이브를 사용하면 접속이 중단될 가능성을 줄일 수 있을 뿐만 아니라 끊어진 연결을 더 빨리 발견할 수 있습니다.
여기 킵얼라이브에 관한 보충 문헌이 있습니다.이 보충 문헌은 킵얼라이브에 대해 자세히 설명하고 있습니다.
http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO
Java에서는 실제 킵얼라이브 시간을 제어할 수 없기 때문에 Linux 커널(또는 proc 기반 OS)을 사용하는 경우 예를 사용하여 변경할 수 있습니다.
- KeepAliveTime (REG_DWORD, 밀리초, 디폴트로는 7,200,000 =2시간을 의미함) : tcp_keepalive_time 에 대한 아날로그
- KeepAliveInterval(REG_DWORD, 밀리초, 디폴트로는 1,000=1초를 의미함) - tcp_keepalive_intvl과 아날로그
- Windows Vista 에는 tcp_keepalive_probes 에 대한 아날로그가 없기 때문에 값은 10으로 고정되어 변경할 수 없습니다.
JAVA 소켓– TCP 접속은 OS 수준인 java.net에서 관리됩니다.소켓에는 소켓 단위의 킵얼라이브 패킷의 타임아웃을 설정하는 기능이 포함되어 있지 않습니다.다만, Java 소켓의 킵얼라이브 옵션을 유효하게 할 수 있습니다만, tcp 접속이 오래된 후 처리에는 디폴트로 2시간 11분(7200초)이 걸립니다.이 원인 연결은 삭제하기 전에 매우 오랫동안 사용할 수 있습니다.이러한 옵션을 설정하기 위해 네이티브코드(c++)를 호출하는 Java Native Interface(JNI; Java 네이티브인터페이스)를 사용하는 솔루션을 찾았습니다.
윈도 OS
Windows 운영체제에서는 keepalive_time 및 keepalive_intvl을 설정할 수 있지만 tcp_keepalive_probes는 변경할 수 없습니다.디폴트로는 TCP 소켓이 초기화되면 킵얼라이브 타임아웃은 2시간, 킵얼라이브 간격은 1초로 설정됩니다.킵얼라이브 타임아웃의 디폴트 시스템 전체 값은 KeepAliveTime 레지스트리 설정을 통해 제어할 수 있습니다.이 레지스트리 설정은 밀리초 단위의 값입니다.
Windows Vista 이후에서는, 킵 얼라이브 프로브(데이터 재발송신)의 회수는 10으로 설정되어 변경할 수 없습니다.
Windows Server 2003, Windows XP 및 Windows 2000 에서는, 킵 얼라이브 프로브수의 디폴트 설정은 5 입니다.킵얼라이브 프로브의 수는 제어할 수 있습니다.Windows 의 경우는, Winsock IOCTLs 라이브러리를 사용해 tcp-keepalive 파라미터를 설정합니다.
int WSAIoctl(
SocketFD, // descriptor identifying a socket
SIO_KEEPALIVE_VALS, // dwIoControlCode
(LPVOID) lpvInBuffer, // pointer to tcp_keepalive struct (DWORD)
cbInBuffer, // length of input buffer
NULL, // output buffer
0, // size of output buffer
(LPDWORD) lpcbBytesReturned, // number of bytes returned
NULL, // OVERLAPPED structure
NULL // completion routine
);
Linux OS
Linux 에는, 킵얼라이브의 서포트가 짜넣어져 있습니다.킵얼라이브를 사용하려면 , TCP/IP 네트워크를 유효하게 할 필요가 있습니다.프로그램은 setsockopt 인터페이스를 사용하여 소켓에 대한 킵얼라이브 제어를 요청해야 합니다.
int setsockopt(int socket, int level, int optname, const void *optal, socklen_t optlen)
각 클라이언트 소켓은 java.net을 사용하여 생성됩니다.소켓. 각 소켓의 파일 기술자 ID는 Java 리플렉션을 사용하여 검색합니다.
언급URL : https://stackoverflow.com/questions/1480236/does-a-tcp-socket-connection-have-a-keep-alive
'programing' 카테고리의 다른 글
평신도 용어로 "static"은 Java에서 무엇을 의미합니까? (0) | 2023.01.19 |
---|---|
JavaScript 어레이 스플라이스와 슬라이스 (0) | 2023.01.19 |
JUnit 4 비교 세트 (0) | 2023.01.19 |
PHP에 파일을 업로드 할 때 $_FILES가 비어 있는 이유는 무엇입니까? (0) | 2023.01.09 |
스킴용 Hadoop 파일 시스템 없음: 파일 (0) | 2023.01.09 |