accept 함수에서....
글쓴이: miso / 작성시간: 월, 2002/12/30 - 11:04오전
제가 지금 서버를 만들고 있는데요...
socket과 pthread를 사용해서요....
그런데....
이상하게 packet을 주고 받기를 못하는 거예요...
그래서.. 이것 저것.... 하다가 알아 낸것이...
accept 함수에서 소켓을 만들잖아요.. 그런데.. 이 소켓이 계속 같은 소켓만 만드네요..
UserSocket = accept(m_ListenSocket, (struct sockaddr *)&UserAddr, (socklen_t*)&nLen);
printf("socket : %u\n", UserSocket);
에서 socket을 printf함수로 찍어 봤던니... 계속 같은 숫자만 찍네요..
window에서는 다른 숫자를 찍어는요...
linux에서는 원래 같은 숫자를 찍나요...
왜 이런 현상이 나타나는지.. 제가 뭘 잘 못 했는지..
제가 pthread를 써서 클라이언트가 접속할때마다 쓰레드를 생성하는데...
이것때문에 세그먼트 디폴트가 나오는 것 같은데...
해결 방법 좀 알려주세요...
일주일째 이것 때문에 일도 못하고 있습니다..
이해가 가기전에 해결해야하는데...
Forums:
음..... 소스가 좀 더 있어야 확인이 가능할거 같은데요....
음..... 소스가 좀 더 있어야 확인이 가능할거 같은데요....
소켓 만든부분 부터 소스를 좀더 올려 주시면...
.
.
제가 그렇게 구현한적이 있거든요.... 잘 동작 합니다.
소스는....
소스는 제가 만든 소스가 아니라 올릴 수는 없고요....
일단 설명을 다시 드리면..
A라를 클래스가 있습니다....
그 클래스를 main 함수에서 선언하고 사용합니다.
A의 Start함수가 있는데...
Start함수에서...
Listen 소켓을 생성하고...
bind하고... listen 한다음...
Start 함수의 일부분입니다.
Start 함수에서..
쓰레드를 생성하고... 그다음에.. ListenThread 함수에서...
accept 함수를 부르는데요...
제가 다시 이것 저것 해보니까...
ListenThread에서.. 다른 쓰레드를 또 생성하거든요...
클라이언트가 접속 할때 마다...
근데...
쓰레드를 생성하는 부분을 빼면.. accept가 다른 소켓을 생성하는데...
이 쓰레드 생성하는 부분만 넣으면.. 같은 소켓을 계속 생성하는 것 같습니다...
그리고.. 쓰레드를 생성하다가 세그먼트 디폴트를 발생하고 그냥 죽어 버리
네요...
왜 그런지....
*^^*
accept 과정중에 오류가..
ListenThread에서 accept후에... 실제 클라이언트와
접속을 담당하는 쓰레드를 생성하신다고 했는데 (이 실제
접속을 담당하는 쓰레드를 클라이언트쓰레드라고 하겠습니다.)
제 생각에는 클라이언트쓰레드가 제대로 동작을 못해서
인듯 싶네요... accept하자 마자 프로그램에서 close처리 해버리면
새로운 클라이언트가 와도 계속 같은 fd가 생성되겠죠..
fd를 잘 넘겨 받았는지 쓰레드에서 체크해보세요
그리고 쓰레드에서 fd닫는 루틴이 있으면 거기에 로그좀 찍어 보구요..
실제적인 작업은 쓰레드가 다하는데,
쓰레드 소스를 봐야 머가 잘못인지 알수 있겠네요..
울랄라~ 호기심 천국~!!
http://www.ezdoum.com
그래서 여러가지 테스트를 해 보았습니다...
여러가지 테스트 결과 pthread에 문제가 있는 것 같아요...
그래서 다음과 같이 이것 저것 빼고 제가 구현한 소스에서.....
쓰레드 생성하는 부분만 간단하게 짜 보았습니다...
소스는 다음과 같습니다.
이 소스를 실행해 본결과....
i를 10으로 하든 20으로 하든...
쓰레드가 8개 까지 밖에 생성이 되질 않아요...
그래서 i를 100으로 바꿔서 돌려 봤더니.. 95, 98까지 밖에 생성하지 못 합니다..
왜 그렇건지...
제가 생성하는 것이 무엇이 틀렸는지.. 조언 좀 부탁드립니다..
아직까지.. 해결 못하고... 이러지도 못하고 저러지도 못하고 있습니다...
linux에서 Multi Thread 구현하는 것이 무지 하게 힘이드네요...
늦었지만.. 모두들 새해 복 많이 받으세요.. ^^;;
*^^*
제 시스템에서는 이상이 없이 잘되는군요..
님께서 올린 소스로 제 서버에서 테스트를 해보니
이상없이 동작을 합니다.
제 서버의 환경은 이렇습니다.
wow6.2up에다가 커널업만 해줬습니다.
Linux version 2.4.19 (root@hyuna.zeroin.co.kr) (gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)) #1 금 9월
20 12:10:53 KST 2002
울랄라~ 호기심 천국~!!
http://www.ezdoum.com
그럼.. linux 버전 문제 인가요?
그럼.. 어떻게 해야 하나요...
제가 window C는 좀 해봤지만.. linux C는 완전 초보라서요...
저의 linux 버전은...
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.95.4/specs
gcc version 2.95.4 20010319 (prerelease)
입니다...
process 생성하는 것이 어려워서.. pthread를 쓰려고 했는데...
어떻게 해결 방법이 없을까요?
wow6.2up에 커널업은 어떻게 해주나요?
*^^*
커널업하기
제가 2.4.x로 업할때 참고한 글입니다.
http://www.wowlinux.com/information/techupview.html?id=47&view=1
울랄라~ 호기심 천국~!!
http://www.ezdoum.com
그건 말이죠~
main thread에서 pthread_join을 호출하지 않았네요
child thread가 생성되고 printf를 실행하기 전에
main thread가 종료되면 어케 될까요??
이해되셨죠??
그럼 즐프~
pthread_join을 사용해봤는데요....
음...
처음에...
pthread_join을 사용해서 만들었습니다..
잘 돌아 가더라고요..
MultiThread로 잘 돌아 가는 줄알았습니다....
근데 좀 이상해서 테스트를 해봤더니...
계속해서 Thread 하나만 가지고 사용하다라고요...
그래서 다중 사용자가 접속하면...
한명이 접속이 끝나고 나서야 그다음 사용자가 결과를 가져가더라고요...
pthread_join이라는 함수가
그 쓰레드가 끝날때 까지 기다리라는 함수라고 하더라고요...
그래서 계속 같은 소켓만 생성하고 객체를 생성하는데 계속 처음에 생성한
객체 하나만 사용하더라고요..
아직도 해결을 못했는데...
제발 좀 누가 알려주세요...
왜 위 소스에서 쓰레드가 개수 만큼 생성이 안돼는지...
MultiThread를 구현 하려면 어떻게 해야하는지 좀 알려주세요..
*^^*
님이 올리셨던거 하곤 쫌 틀리지만....
제가 했었던 것을 지울건 지우고 올립니다....
이런식으로 하는건 아주 잘 되거든요... 커넥션이 하나 맺어질때 마다
쓰레드가 하나씩 생성됩니다.
이런 방식으로 짜 봤는데요....
우선 저에게 소스를 보여 주셔서 감사합니다..
보여주신 소스 방식으로 짜 봤는데요...
제가 클라이언트가 10개 동시 접속해서 쓰레드를 10개 생성하게 했는데요..
6개 까지 생성하고 세그먼트 디폴트를 생성하고 죽어 버려요..
틀린점은..
첫째 signal 함수를 사용하지 않았고요...
둘째 쓰레드 함수에 그러니까.. run_thread 함수에 인자값 arg를 구조체로 넘겨 주겨든요..
구조체에 new_sock을 담아서요...
구조체에는 Class 객체를 두개 가지고 있습니다...
쓰레드 인자 값으로 구조체를 넘겨서 문제가 되나요?
아님 signal 함수를 사용하지 않아서 문제가 되나요?
이유가 뭔지 정말 모르겠습니다..
조언 좀 주세요... ㅜㅜ
*^^*
흠... 인자로 구조체를 넘기는 건 문제가 안되구요.....각각
흠... 인자로 구조체를 넘기는 건 문제가 안되구요.....
각각 쓰레드에 넘겨지는 구조체는 역시 각각 할당된거겠죠?...
그리고 시그널과 쓰레드가 문제가 많긴하지만... 여기선 별 문제가 안될거 같구요...... segmentation fault 라니.. 문제가 있는건 확실한뎅...ㅡ.ㅡ
일단은 님 시스템에서 쓰레드가 정확히 만들어 지는지 집고 넘어가야 할거 같군요...
님이 작성하신 테스트 코드에 한두줄 추가했습니다.... 이 코드로는 쓰레드가
올바르게 생성되야 할거 같은데요...
소스를 테스트 해보았습니다...
먼저 이렇게 답변을 주셔서 정말 감사합니다...
그래도 어려운 상황에서 도와 주시는 분이 있다니 힘이 됩니다.
님께서 써주신 소스로 저의 컴퓨터에서 실행을 해 보았습니다.
쓰레드가 잘 생성이 됩니다...
그런데 문제는 이것을 소켓 생성하는 부분에 넣으면...
즉 sleep이라는 함수를 쓰레드 생성하는 부분에 넣으면...
그러니까...
1월 3일 보여주신 소스에서요...
================
for(;;) {
while( (new_sock = accept(sock, (struct sockaddr *)NULL, NULL)) < 0 ) {
if( errno == EINTR )
continue;
else {
syslog(LOG_POINFO, "create_socket() : accept() : %m"); exit(1);
}
}
if( pthread_create(&tid, NULL, &run_thread, (void *)new_sock) ) {
syslog(LOG_POINFO, "pthread_create( run_thread ) : %m");
close(new_sock);
}
sleep(2); //====> 추가부분
}
===================
넣으면요.. 세그먼트 디폴트는 안나는데요...
계속 같은 소켓을 생성하더라고요...(즉 new_sock의 값이 일정하게 4만 나옵니다.)
그리고 제가 미리 객체를 열개를 생성하는데요..
계속해서 객체 하나만 사용합니다...
만약에 동시 사용자가 100이상이 되면 문제가 되지 않을까요?...
어떻게 해결 방법이 없을까요?...
*^^*
음... 님의 테스트 코드에 sleep를 넣었던것은 자식 쓰레드들이 모두
음... 님의 테스트 코드에 sleep를 넣었던것은 자식 쓰레드들이 모두 끝날때 까지 충분히 기다리기 위해 넣었던거구요.. 제가 올린 코드에 sleep을 주는 건 쫌 문제가 있군요.... accept되고 쓰레드가 만들어지고 2초 전에 그 쓰레드가 종료된다면 2초 후에 accept가 다시 동작 하니까 계속 같은 소켓만 생성이 되겠죠... 객체도 하나만 계속 사용할거구요.....
세그멘테이션 폴트가 나는건 추측건데(소스가 없으니..) 객체들 사용에 있어
충돌이 나서 죽는것 같구요.... 제가 보여드린 소스를 그대로 컴팔해서(약간은 수정..^^) (객체가 포함된 구조체를 넘기지 말고..) 정상적으로 동작을 한다면....
님이 작성하시고 있는 소스에서 각각의 쓰레드들에서 객체들이 사용되는데..
논리적인 문제가 있다고 밖에 말씀드릴수 없을것 같군요....
클래스가 쓰레드들마다 독립적으로 잘 사용되는지 혹시 쓰레드들간 꼬이지는 않는지 살펴보시는게./.... 흠...
해결 했습니다...
님의 말씀을 듣고 소스를 하나하나 뜯어 봤습니다...
그랬더니.. 메모리 해제를 안해야 하는 곳에서 메모리 해제를 해서...
그런 현상이 나타나더군요....
정말 감사합니다..
새해 복 많이 받으시고요...
항상 건강하시고 항상 행복하세요... ^^
*^^*
댓글 달기