2009-10-15 3 views
2

내 TCP 서버에서 한 번에 하나의 연결 만 허용하려고합니다. 백 로그 길이가 0이 아닌 청취 방법을 알려주십시오.Winsock2 : VC++에서 수신 대기 백 로그를 사용하여 한 번에 하나의 클라이언트 연결 만 허용하는 방법

나는 코드를 사용하여 (아래에 나와 있음),하지만 내가 2 명의 클라이언트를 하나씩 실행하면 둘 다 연결된다. 난 winsock2와 VC + +를 사용하고 있습니다.

듣기 (m_socket, -1);

백 로그로 0을 전달하는 것도 작동하지 않습니다.

답장을 기다리는 중입니다.

감사합니다,
immi

답변

6

, 당신은 조건부 동의 메커니즘을 사용할 수 있습니다 :

이만큼 자동으로 들어오는 SYN 패킷에 SYN-ACK 답장을 보낼 수있는 스택의 동작을 변경
SOCKET sd = socket(...); 
listen(sd, ...); 
DWORD nTrue = 1; 
setsockopt(sd, SOL_SOCKET, SO_CONDITIONAL_ACCEPT, (char*)&nTrue, sizeof(nTrue)); 

연결 백 로그 공간을 사용할 수 있습니다. 대신 프로그램은 정상적으로 연결을 받아 들여야한다는 신호를받습니다 - select(), WSAEventSelect(), WSAAsyncSelect() ...- 당신은) (WSAAccept를 (전화) 대신의 동의 :

sockaddr_in sin; 
WSAAccept(sd, (sockaddr*)&sin, sizeof(sin), ConditionalAcceptChecker, 0); 

당신은 들어오는 연결 정보를보고 연결을 허용할지 여부를 결정하는 기능 ConditionalAcceptChecker()를 작성합니다. 귀하의 경우에는 이미 연결을 처리하는 동안에 만 CF_REJECT을 반환 할 수 있습니다.

이 메커니즘은 Winsock 2에만 해당됩니다. 이식 가능한 동작이 필요한 경우 프로그램에 이미 연결되어있는 동안 다른 게시물의 청취 소켓을 닫는 것이 좋습니다.

+0

좋은 답변, 워렌 영. ur 시간과 답장을 보내 주셔서 감사합니다. – immi

+0

니스, 나는 그것에 대해 잊어 버렸습니다 :) 클라이언트가 서버가 연결을 거부하면 무엇을 보게됩니까? TCP 수준에서 –

+0

RST, Winsock 수준에서 WSAECONNREFUSED. –

2

당신은 1과 동일 백 로그를 설정할 수 있습니다, 이것은 당신이 원하는 연결의 수 때문이다.

하지만 AFAIK 대기열 크기에는 아무런 보증이 없습니다 (this doc은 BSD에서 1.5 * 백 로그라고 말합니다).

IMHO, 어떤 제한을 적용한 후 accept() 연결을 사용하지 않으면 수동으로 연결 수를 제어하는 ​​것이 좋습니다.

+0

elder_george, 질문에 답해 주셔서 감사합니다. 하지만 TCP 연결을 시도 할 때마다 클라이언트 연결 요청이 실패하는 방식이 있습니까? – immi

1

나는 단지 accept 만 말할 것입니다. 서버에서 한 번에 하나의 클라이언트 만 원할 경우 하나의 스레드 만 사용하여 처리 할 수 ​​있습니다. 백 로그는 수락을 위해 시스템에서 처리하는 보류중인 연결 수만을 제한합니다 (첫 수락 후에 큐가 다시 비어서 다음 클라이언트가 백 로그에 들어감).

1

그건 듣기 백 로그가 아니야.

수신 대기 로그는 보류중인 연결에 사용되는 대기열에 영향을 미치며 TCP 스택이 대기중인 연결을 대기열로 받아 들여 수락하도록 허용합니다.

원하는대로하려면 하나의 연결을 허용하고 수신 대기 소켓을 닫아야합니다. 단일 클라이언트로 작업을 완료하면 청취 소켓을 다시 만들고 새 연결을 수신 대기 할 수 있습니다. 이것은 하나의 클라이언트가 당신에게 연결하는 것 이상의 것을 방지 할 것입니다. 그러나 클라이언트가 당신이 "한 번에 하나씩"실행하고 연결을 수락한다는 것을 알 수있는 방법이 없습니다. 연결을 관리하는 클라이언트를 제외한 모든 클라이언트는 자신이 존재하지 않는다고 생각할 것입니다.

청취 소켓을 열어두고 모든 연결을 수락하는 것이 더 나은 디자인 일 수 있지만 일단 "하나"의 활성 연결을 수락하면 간단히 수락 한 다음 클라이언트에게 응용 프로그램 수준 메시지를 보내어 수락 할 수 없음을 알립니다 더 많은 연결 또는 그렇게 할 수 없다면 단순히 새 연결을 닫으십시오. 당신은 참으로 만 사용 Winsock을 2 응용 프로그램을 제한 할 수있는 경우

+0

제안 해 주셔서 감사합니다. 나는 UR 아이디어를 얻었다. 그것의 좋고 실제적인. 나는 듣지 않는 소켓을 닫는 방법으로 갈 수 있지만, 두 번째 접근법을 심각하게 생각하려고합니다. 지식에 대해서만 묻고 싶습니다. 소켓에 상태를 가져올 방법이 있습니까? 듣기 전 이었습니까? 예를 들어, 소켓을 바인딩하고 현재 수신 대기중인 경우 소켓을 닫지 않고 소켓의 수신 대기 모드를 취소 할 수 있습니다. 답장을 기다리는 중입니다. – immi

+0

내가 아는 한, 그렇게 할 방법이 없습니다. 어쨌든, 왜 귀찮게합니까? –

관련 문제