문제

Listen (FD, 백 로그)이라고 불렀을 때 소켓을 발행 할 수 있습니까?

편집 : 나 자신을 명확하게하지 않는 나의 실수. 소켓에서 일시적으로 배출 할 수 있기를 원합니다. Close ()에게 전화를 걸면 M2LS 상태에 소켓이 남겨두고 다시 열지 못하게합니다 (또는 더 나쁘게도 일부 사악한 프로그램은 해당 소켓에 바인딩 할 수 있습니다).

일시적으로 무기력은이 앱이 순간에 더 이상 요청을받을 수 없다는 상류로드 밸런서에게 신호를 보내는 방법 (가장 좋은 방법이 아닐 수도 있음)이 될 것입니다.

도움이 되었습니까?

해결책

일부 소켓 라이브러리를 사용하면 들어오는 연결을 구체적으로 거부 할 수 있습니다. 예를 들어: GNU의 commonc ++ : tcpsocket 클래스 a 거부하다 방법.

BSD 소켓에는이 기능이 없습니다. 당신은 할 수 있습니다 동의하기 연결 및 즉시 닫다 소켓을 열면서 :

while (running) {

  int i32ConnectFD = accept(i32SocketFD, NULL, NULL);
  while (noConnectionsPlease) {
    shutdown(i32ConnectFD, 2);
    close(i32ConnectFD);
    break;
  }

}

다른 팁

소켓을 닫은 후에는 프로그램에서 소켓이 "사용중인"임을 여전히 알려줄 수 있습니다. 이것은 내가 정확히 알지 못하는 이상한 점 때문입니다. 그러나 소켓에 대한 맨 페이지는 "SO_REUSEADDR"이라고 불리는 동일한 소켓을 재사용 할 깃발이 있음을 보여줍니다. "setsockopt ()"를 사용하여 설정하십시오.

닫아. 내가 기억하는 것처럼;

close(fd);

편집 된 버전의 질문을 기반으로, "무효"또는 Close ()를해야할지 모르겠습니다. 두 가지 옵션이 떠 오릅니다.

1) Listen ()를 호출 한 후에는 (논리적으로 충분 함) accept ()를 호출 할 때까지 연결이 실제로 허용되지 않습니다. 단순히 소켓 활동을 무시하고 준비가 될 때까지 수락 ()을 연기함으로써 "무인"할 수 있습니다. 인바운드 연결은 포트가 듣기 모드에서 열릴 때 생성 된 대기열에 백 로그를 시도합니다. 백 로그 큐가 스택에 가득 차면 추가 연결 시도가 바닥에 떨어집니다. Accepts ()로 재개되면 백 로그를 빠르게 탈취하고 더 많은 연결을 준비하게됩니다.

2) 포트가 실제로 임시로 완전히 닫히기를 원한다면, 인바운드 연결 시도가 네트워크 스택에 도달하는 것을 방지하기 위해 커널 레벨 패킷 필터를 포트에 동적으로 적용 할 수 있습니다. 예를 들어, 대부분의 *NIX 플랫폼에서 BERKELEY 패킷 필터 (BPF)를 사용할 수 있습니다. 즉, 플랫폼의 방화벽 기능을 사용하여 관심 포트에 들어오는 인바운드 패킷을 떨어 뜨리고 싶습니다. 물론 이것은 플랫폼마다 다르지만 가능한 접근법입니다.

나는 그것이 상류 하중 밸런서를 알리는 좋은 방법이라고 생각하지 않습니다. 메시지가 통과되기 전에 실제로 서버에 연결을 보내야합니다. 이러한 연결은 아마도 거부 될 것입니다.

마찬가지로, 청취 소켓을 닫을 때 계류중인 연결은 데이터없이 닫히게됩니다.

업스트림로드 밸런서에 신호를 보내려면이를 수행하기위한 프로토콜이 있어야합니다. TCP를 남용하려고하지 마십시오.

다행스럽게도 클라이언트가 일반적인 웹 브라우저 인 경우 끔찍한 많이 사용하지 않을 수 있습니다. 단순히 소켓을 닫으면 일반적으로 사용자에게 투명하게 재 시도합니다.

무기력 할 명시적인 방법은 없습니다!

당신도 할 수 있습니다 close(fd) 또는 shutdown(fd, how)

fd is the socket file descriptor you want to shutdown, and how is one of the following:

0 Further receives are disallowed

1 Further sends are disallowed

2 Further sends and receives are disallowed (like close())

기본 수준에서 소켓은 열리거나 닫힙니다 (여기서는 TCP/IP 상태 다이어그램의 멋진 것을 무시할 것입니다).

소켓이 닫히면 데이터를 보낼 수 없습니다. 개방 된 경우, 버퍼링 알고리즘이 "충분히!"울부 짖을 때까지 TCP/IP 스택에 의해 들어오는 데이터가 허용되고 인정됩니다. 이 시점에서 추가 데이터는 인정되지 않습니다.

내가 볼 수있는 두 가지 선택이 있습니다. "무선"을 원할 때 소켓을 닫고 나중에 다시 열고 나중에 다시 열십시오 - so_reuseaddr 플래그와 함께 setsockopt ()를 사용하여 time_wait2가 만료되기 전에 잘 알려진 포트에 다시 반짝이도록 할 수 있습니다.

다른 선택은 소켓을 열어 두지만 '바쁘다'는 동안 소켓을 열어주지 않는 것입니다. 요청에 대한 응용 프로그램 수준의 승인이 있다고 가정하면 밸런서를로드하면 응답을받지 못하고 그에 따라 행동 할 수 있습니다.

편집 된 질문을 기반으로 한 다소 못생긴 접근 방식은 다음과 같습니다.

일반적인 백 로그로들을 수 있도록 소켓을 엽니 다. 진행하다.

"종료"를 원할 때 1과 SO_Reuseaddr의 백 로그가있는 두 번째를여십시오. 첫 번째를 닫으십시오. 재개 할 준비가되면 일반 백 로그가있는 다른 소켓으로 저글링하십시오.

당신이 닫고있는 소켓에서 수락 대기열을 배출하는 것에 대한 까다로운 세부 사항은 여기에서 살인자가 될 것입니다. 아마도이 접근법을 불가능하게 만들기에 충분한 살인자가있을 것입니다.

반드시 이것이 좋은 생각이라고 생각하지는 않지만 ...

당신은 두 번째로 듣는 것을 부를 수 있습니다. POSIX 사양은 말하지 않습니다. 아마도 당신은 "무기력"을 원할 때 백 로그 매개 변수 0으로 두 번째로 부를 수 있습니다.

0의 백 로그로 청취가 호출 될 때 발생하는 일은 구현 된 구현이 정의 된 것 같습니다. POSIX 사양이 말합니다 5월 백 로그 매개 변수가 0 인 경우 일부 구현이 모든 연결을 거부하도록 선택할 수 있음을 의미합니다. 그러나 아마도 구현은 0 (아마도 1 또는 SomaxConn)을 통과 할 때 약간의 양수 값을 선택할 가능성이 높습니다.

질문은 어떤 종류의 소켓을 말하지 않았습니다. Unix 소켓 인 경우 이름 바꾸기 (2)로 중지하고 듣기 시작할 수 있습니다. Unlink (2)로 영구적으로 듣기를 중단 할 수 있으며 소켓이 열려 있으므로 백 로그를 계속 서비스 할 수 있습니다. 이 접근법은 이전에 사용 된 적이 없지만 직접 탐색하고 있습니다.

당신은 이미 소켓 API를 통해이 작업을 수행 할 수없는 것에 대한 답을 얻었습니다.

다른 OS 메소드 (즉, 호스트 Firwall/IPTables/IPFilter)를 사용하여 임시 거부 규칙을 설정할 수 있습니다.

나는 대부분의로드 밸런서가 연결 문제를 인식하기 위해 제공하는 가능성이 약간 제한되어 있음을 발견했습니다 (대부분은 합법적 인 연결 시도에 대한 답변이 아니라 Connect 프로브에서 RST 만 인식합니다.)

어쨌든, 당신이 불가능 성을 감지하는 프로브에 의해 제한되어 있다면, 당신은 HTTP 요청 또는 ftp 로그인 또는 동의 후 간단히 닫으면 인식하는 것들을 수행하는 응용 프로그램 레벨 프로브를 설정합니다. "500 서비스를 사용할 수 없음"과 같은 오류 메시지를 해석 할 수도 있습니다. 어쨌든 더 깨끗해 보입니다. SNMP를 사용하면 일부로드 밸런서는 결과를로드 힌트로 사용할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top