Connect 질문이어서
글쓴이: merds / 작성시간: 금, 2003/08/01 - 1:39오후
아주 빠른 답변에 놀랬습니다. 감사합니다.
connect를 이용 열린포트를 알아 낼려고 합니다.
문제의 핵심은 대상포트들에 대해 컨넥션을 이용 접속할때
방화벽에 막힌 포트 접속시 딜레이시간이 기니깐
접속을 중간에 포기하고 닫힌포트로 가정후...(어차피 방화벽에 막혓으니)
다음 포트를 검사하도록 하고 싶습니다.
근디 아래처럼하니 다음 남은 포트 검사 없이
스레드가 죽으며, 또다른 쓰레드를 실행시킵니다.
머 이런식으로 진행되다 결국 뻗어요 ㅡㅜ
아래의 내용이 관련 소스 일부 입니다.
#include "TCP_util.h" #include "PortScan.h" int arMainPort[53]={13,20,21,22,23,24,25,27,29,31,33,35,37,38,39,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,66,67,68,69,70,71,76,78,79,80,88,92,107,110,113,115,119,137,138,139}; int iConTimeout = 0; int main_pro(int socketfd) { ... 중략 ... switch(nMsg) { case MSG_CASE1: for(nindex=0;nindex<53;nindex++) { ret =[color=brown]PortScan[/color](addr,arMainPort[nindex]); if(ret == 1) arResult[nindex] = 'o'; else arResult[nindex] = 'c'; } break; default: printf("Command Error %d..\n",nMsg); return -1; } ... 중략 ... } int PortScan(struct sockaddr_in addr, int port) { int sockfd; struct sockaddr_in destaddr; int pok,data,flags; fd_set rset, wset; sockfd = socket(AF_INET,SOCK_STREAM, 0); destaddr.sin_family = AF_INET; destaddr.sin_addr = addr.sin_addr; destaddr.sin_port = htons(port); bzero(&(destaddr.sin_zero), 8); signal(SIGALRM,ConTimeOut); alarm(5); // 연결... 연결... pok = connect(sockfd, (struct sockaddr *)&destaddr, sizeof(struct sockaddr)); if(iConTimeout) { close(sockfd); return 2; } // 연결 되면? 0을, 아니면 -1을 리턴 if (pok == 0) { printf("[ %d ] OPEN\n",port); close(sockfd); // 연결 끝 return 1; } else { printf("[ %d ] Close\n",port); close(sockfd); // 연결 끝 return 2; } alarm(0); iConTimeout = 0; } void ConTimeOut() { printf("Connect time OUT\n"); iConTimeout = 1; // 전역변수 }
Forums:
main_pro 라는 함수가 쓰레드 시작 함수입니까? 내부에 루프를 보면
main_pro 라는 함수가 쓰레드 시작 함수입니까? 내부에 루프를 보면 아닌 것 같구요. 왜 쓰레드라는 것이 필요한지요? 동시에 여러접속을 다룬다는 면에서나 꺌끔한 면에서나 다른 분들이 계속 말씀하신 select 를 사용하심이...
하시려는 의도가 각 쓰레드에 원하는 포트를 쥐어주고 동시에 '시작'하게 해서 그 결과를 얻으실려는 것이라면... 지금 방식으로는 좀...
그럼, 이만...
main_pro가 스레드의 시작함수 맞습니다.내부의 루프는 단지
main_pro가 스레드의 시작함수 맞습니다.
내부의 루프는 단지 포트별로 컨네트를 위해서 도는것입니다..
이런식으로 포트별 connect만을 시도해서 열린포트를 알려고 하거든요
(제 생각에 가장 간편한듯하여)
select문을 쓰더라도 이루프는 존재해야 될것 같아서요
제 생각에 문제가 있으시면 알려주세요
참고
쓰레드를 생성해서 포트접속을 시도하는 방법 말고,
소켓생성한후 소켓을 non-blocking으로 세팅하고, 연속적인 접속을 수행하는
형태로 바꾸는 것이 좋아 보입니다. 이렇게 하면 connect()의 블록킹 호출을
회피할 수 있습니다.
스티븐스의 유닉스 네트워크 프로그램책에도 web client를 이런 유형으로
짜서 테스트한것이 있으니 참고하세요.
물론 유닉스네트워크프로그래밍 책에서의 web client는 진정한 web client는
아닙니다. 단지 단순하게 테스트를 위한 프로그램입니다. 그래서 보기는 더
쉽겠지요.
------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.
접속한 ip를 알아내서portScan함수에서포트별로 단순히 con
접속한 ip를 알아내서
portScan함수에서
포트별로 단순히 connect가 되는지 안되는지 되는 루틴이거든요
portscan함수를 보시면 새로운 소켓을 생성해서
포트별로 컨넥트를 시도 하거든요
여기 조언대로 그 부분만 바꺼주면 되는거 아닌가요??
일단 전 그부분만 바꿔도 될것같아서 계속 fcntl()함수 alarm()함수를 이용하는
방법을 번갈아 가면서 시도 하고 있는디 잘안되서요
이런식으로 해결이 불가능하다면...전체를 뜨어야 겠지만
제가 잘못 생각하고 있는가요...
해결 되었습니다.
신경 써 주신 분들께 감사합니다.....^^;
PortScan()함수부분을
alonecrow님께서 사용하신 함수를 약간 수정하여
사용하니 간단히 해결되네요
테스트를 계속 해봐야 겠지만...
다시한번 감사
alonecrow님의 함수는 요기 있어요(필요하시면 참고)
http://bbs.kldp.org/viewtopic.php?t=21634&highlight=connect+timeout
1. 쓰레드는 공짜가 아니라는 것. (최소한 쓰레드 속성이라도 사용해야.
1. 쓰레드는 공짜가 아니라는 것. (최소한 쓰레드 속성이라도 사용해야...)
2. 시그널도 그렇게 효율적인 호출 순서가 아니라는 것 (캐쉬라인 다 깨지는 것 아닌가요?)
3. alarm의 만료시간전에 루틴을 빠져나갔을 때 혼자남은 시그널 함수는? (제대로 알람을 끄지 않고 탈출하는 경우가 위 소스에는 있다는 것. 4번과 연동된 문제점)
4. 시그널이 쓰레드별로 동작한다고 하더라도 그 완료를 나타내는 것으로 전역변수를 쓰고 있다는 점. (쓰레드 키를...)
5. 만약 하나의 IP에 여러개의 포트를 스캔하는 것이라면 위 소스 구조는 쓰레드를 써봤자 소용없다는 것 (포트별로 쓰레드를 쓰고자 하시는 의도가 아닌가요?)
6. 만약 쓰레드 하나가 하나의 IP를 담당하고 그 안에서 포트를 스캔하는 구조라고 한다면 지금 구조로는 최악의 경우 '타임아웃 * 53' 이라는 시간이 소요됩니다. 물론 5번의 경우도 지금 구조라면 같은 시간이 걸리겠습니다.
등등이 문제가 될 소지가 있다고 생각합니다.
비동기 소켓에 select를 사용하는 것이 적절하지 않을까요... 당장에 동작시간을 아주 짧게 할 수 있을 것같은 이 들뜬 기분은??? -_-;
그럼, 이만...
댓글 달기