listen()대한 질문입니다.
글쓴이: chakan01 / 작성시간: 금, 2003/07/18 - 11:43오후
간단한 서버프로그램에서 소켓생성하고 bind한후에 listen(sock_fd, 1) 로 한다음에 accept로 기다리고 있습니다.
int listen(int s, int bakclog); 로 정의가 되어있는데,
bakclog는 대기큐의 최대갯수로 알고있습니다.
그러면, 위와같이 backlog를 1로 세팅을 하고,
클라이언트프로그램에서 소켓생성후 connect를 시도하면 당연히 서버에서는 accept를 합니다.
이후 클라이언트에서 계속 같은포트로 connect를 시도해도 connect함수가 에러를 리턴하질 않고 계속 connect가 성공합니다.
listen server가 없으므로, connect가 에러를 리턴해야 하지 않나요?
Forums:
간단히...
accept() 함수가 접속한 클라이언트에 대한 소켓을 새로 생성해 리턴해 줍니다. 결국, 그 클라이언트에 대한 포트가 새로 할당되고...리슨닝 중인 포트는 계속해서 리스닝을 할 수 있습니다.
보통 다음과 같은 구성이겠죠?[code:1]handle = s
보통 다음과 같은 구성이겠죠?
그런데 여기서 "뭐하는겨" 하는 부분에서 엄청난 지연이 발생한다면
그동안은 listen에서 지정된 백로그만큼의 연결은 성공합니다.
하지만 그 이상을 지연되면 연결은 실패합니다.
그래서 "뭐하는겨" 하는 부분은 쓰레드나 포크로 재빨리 넘겨버리고
다시 accept로 가는 시간을 줄입니다.
그래서 대부분 listen의 백로그는 5정도면 충분하다는 예기가 있고요.....
만약 백로그가 1개로 되어 있고
accept한후 다음 accept하기까지의 시간
즉, accept를 하지 않고 대기하는 시간동안의 연결은 받지 못하는 사태가 발생합니다.
질문하신분의 결과와 다른듯 하지만 소스보면 증거를 잡아드리죠.
[code:1]코드는 다음과 같이 간단합니다.server쪽 코드.
열씨미!
어? 제 실력 부족탓인지...제가 보기엔 하나의 client를 접
어? 제 실력 부족탓인지...
제가 보기엔 하나의 client를 접속 받은후, 더이상 받지 못할것 같습니다만...
listen 함수에 적어주는 숫자는 "대기열"이라 알고 있습니다.
"동시 접속자 수"를 설정해 주는 것으로, 동일한 시간 또는 약간의 지연 탓으로 일시적으로 접속을 받아주지 못할경우 연이어 오는 접속 요청을 넣어두는 큐 정도로 생각하시면 될것 같습니다.
그리고.. 이것을 이용한 해킹방법으로... 윽.. 이름은 모르겠네요. ^^;;
암튼 connect 요청을 한번 하고, 그쪽에서 다시 확인을 위해 이쪽으로 메세지를 보내면.. 그것에 대한 응답을 하지 않도록 만듭니다.
이 작업을 while문으로 돌리면, 언젠간 listen 큐가 모두 차 버릴것이며, 그것은 더이상의 새로운 사용자의 접속 요청을 받아 들일 수 없을 것입니다.
이렇게 되면 각종 서버측의 리소스가 널널히 남는다 할지라도 마치 죽은것처럼 보이겠죠?
음... 왜 또 말이 샜을까..?
아무튼 그냥.. 그런것도 있다는 말이었습니다. ^^;;
아마 지금은 저런 방법 막히지 않았을까 싶은데.. 그렇겠죠?;;
에고.. 초보의 '나름대로' 답변 이었습니다.
[재질문] 좀 이해가 안가는 부분이 있네요
답변 주신분들에게 감사드립니다.
스티븐아저씨가 쓴 책에서 보면,
listen에 backlog는 대기큐의 최개갯수라고하며, 이것은 imcomplete connection queue와 completed queue 두개 모두 합한것의 갯수라고 되어있는것 같습니다.
그럼 서버가 클라이언트로부터 SYN J을 받으면, 우선 imcomplete queue에 하나가 쌓이고, 이어서 클라이언트에게 SYN K, ack j+1를 줍니다.
클라이언트가 이것을 받으면 conncet함수가 리턴됩니다.
그리고 서버에게 ack K+1을 주고 서버가 이를 받으면 accept가 리턴이 된다고 나와있습니다.
그러면, listen(sock_fd, 1)로 세팅후에 이후에 클라이언트가 서버에게 connect를 요청하면, 서버의 imcomplete queue에 계속 쌓일것 같습니다.
현재 위의 코드로보면 fork()를 안하므로 recv()에 블록이 되어있을것이고,
서버의 대기큐의 갯수를 1로 했음에도 클라이언트의 connect는 에러를 내지 않습니다.
도저히 잘 이해가 안갑니다...
열씨미!
[quote="chakan01"]여기서에서 connect를 연속으로 호출
listenQ는 accepted 되기 전에 대기하는 곳이니깐...
아마 님의 말대로라면...
backlog를 0으로 하면은 원하는 결과를 얻을 수가 있을 겁니다.
그렇지 않고...
1로 한다고 한다면...
처음 접속
두번째 접속
세번째 접속 - 여기에서 에러를 뱃으면서 뻗을 겁니다.
확인을 해보세요...
물론 첫번째, 두번째 접속 중인 상태에서 세번째 접속을 시도...
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
backlog값을 0으로 하면 처음 connection부터 connect
backlog값을 0으로 하면 처음 connection부터 connection refused error가 나네요.. --;
열씨미!
그 1이 하나를 뜻하는 것이 아니라 OS 마다 틀린 어떤 상수값이 곱해진
그 1이 하나를 뜻하는 것이 아니라 OS 마다 틀린 어떤 상수값이 곱해진다고 언뜻 본 것 같은데요... 맞나요?
댓글 달기