|
장비를 소켓통신 으로 감시해서 데이타 베이스에 저장하는 프로그램입니다.
프로그램을 시작하면 데이타베이스에서 IP와 PORT를 읽어와서 연결을 시도하고 연결된 장비의 데아타를 수신해서
처리를 합니다.
기본은 수신방식이지만 주기적으로(10분 간격) 폴링을 하고 다시 수신모드로 전환합니다.
그런데 처음 실행하면 잘 동작을 합니다. 데이타베이스에도 데이타 처리 결과가 잘 저장되구요.
그러다가 "응답없음" 상태가 되어서 전혀 데이타 처리를 하지 못하고 있습니다.
어떤때는 1시간만에 또 어떤때는 3일 정도 지나서 "응답없음" 상태가 되어 버립니다.
감시하는 장비의 갰수가 50개가 넘는데 몇개정도는 연결이 안됩니다. (랜 연결이나 장비의 점검등으로 케이블을 뺄 경우 있음.)
그래서 5분 간격으로 다시 연결을 시도 합니다. 이럴때 정상적이면 바로 연결이 되지만 연결이 안될때는 장비 1개당 약 20초가 걸립니다.
몇개 장비가 이럴경우 1분 이상 "응답없음" 상태가 되었다가 다시 실행을 합니다.
그리고 쓰레드를 책과 예제를 통해서 적용을 했습니다.
"응답없음" 에 대해서 자료를 찾다보니 "메모리 관리", "쓰레드의 데드락 상태", "무한루프" , "block 상태" 등이 있더라구요.
그래서 배열변수등 일일히 소스를 찾아 봤습니다. 아직은 이상은 못찾았구요. 쓰레드도 혹시 몰라서 전에 사용하던
순차적으로 감시하는 방식으로 바꾸고 데이타의 송신과 수신 모두 select 함수를 사용해서 non block 방식으로 사용하고 있습니다. ( #include <winsock2.h> )
무한루프 사용하는 부분도 없구요.
수신부분 아래 소스 일부 첨부했습니다.
for 안에 Application->Processmessages(); 이함수를 추가해봤습니다.
프로그램을 시작하면 장비와 연결하고 데이타 수신할때 바로 프로그램이 종료가 되어버립니다.
몇주일째 고생을 하고 있습니다.
원인부분만 정확히 알아도 이렇게 답답하지는 않을것 같네요.
왜 그런지 전혀 감이 안오네요.
환경은 개발은 window xp 에서 했구요.
서버환경은 windox 2003, sql 2000 서버입니다.
감시프로그램은 서버에서 구동하고 있구요.
서버 pc는 hp 제품입니다.
아시는분 부탁드립니다.
void cSockUtil::read_sock()
{
중략...
for(int i=0; i<장비총갯수; i++)
{
if(cli[i].in_use == NO_SOCK)
continue;
FD_SET(cli[i].cli_sock, &fd_read);
FD_SET(cli[i].cli_sock, &fd_except);
nfds = i;
s = select(nfds, &fd_read, NULL, &fd_except, &tout);
// Application->Processmessages();
if(s > 0)
{
if( FD_ISSET(cli[i].cli_sock, &fd_except) )
{
#ifdef DEBUG
#endif
close_sock(i);
}
if( (FD_ISSET(cli[i].cli_sock, &fd_read)) )
read_sock(i);
}// if s
}
}
//-------------------------------
void cSockUtil::read_sock(int s)
{
char buf[1024];
int rtn;
memset(buf, 0x00, sizeof(buf));
rtn = recv(cli[s].cli_sock, buf, 1024, 0);
if(rtn<=0) {
#ifdef DEBUG
sprintf(m_szDebugBuf, "Client 읽기 실패 from: %s, Return: %d",
inet_ntoa(cli[s].cli_addr.sin_addr), rtn);
#endif
FD_CLR(cli[s].cli_sock, &fd_read);
close_sock(s);
}
else
tpoll.Receiver(s, rtn, buf); // 데이타 처리 함수 호출
}
//---------------------------------------------------------------------------
|