none
Winsock Server Service Error 1053 The Server did not ..start..or control ..: RRS feed

  • 질문

  • 하이

    나는 우선  다음과 같은 서비스 프로그램을 제작 하였다.

    1. Winsock 서버 프로그램
    2. VS2013 Comunit 버전으로 컴파일
    3. Windows Server 2013 Stadard

    위 상태에서 소스는 검증을 거쳤고,
    디버그 모드로 컴파일 된 것을
    servicesock -i 로 실행 시 서비스 메니저에 등록이 되었고,
    servicesock -u 로 서비스가 삭제 되었음을 확인 하였다.
    servicesock -i 상태 에서
    서비스 매니저의 시작 버튼을 클릭 하여 정상 구동 되었음을 확인 하였다.

    물론 클라이언트 프로그램을 작성하여, 접속 및 패킷 수신과 송신이 정상적임을 확인 한 것이다.


    그러나 이 서비스 코드를 수정하지 않고...
    릴리즈 모드에서 컴파일 한 결과
    Install과 UnInsatll은 정상적이었으나...
    시작버튼 클릭 하면
    다음의 오류가 나온다.

    .Net 서비스 팩 1을 설치하였으나, 지원하지 않은 것어서 해당 OS에는 설치가 되어 지지 않았다.

    물론 핫픽스 또한 2003 버전과 호환성이 없는듯 하다. 설치가 되어 지지 않았다...

    나는  Windows Server 2013 Standard를 사용함을 다시 알려드린다.

    구글에서 기타 관련 내용을 보았지만...
    위 상황에 맞는 것을 찾지 못했다.

    디버그 모드로 컴파일 된 것은 정상 작동 한다.

    따라서 코드상의 문제 보다는 환경적 요인일 것으로 보인다.

    위와 같은 것에서 해결한 부분 계시면 알려 주길 바랍니다.
    2015년 10월 13일 화요일 오전 5:02

모든 응답

  • "Error 1053: The service did not respond to the start or control request in a timely fashion" 오류 메시지는 서비스 제어 관리자에 대한 서비스 통지를 제한 시간 내에 수신하지 못하여, 서비스 제어 관리자가 서비스 호스팅을 위한 프로세스를 종료했을 때 표시됩니다.

    Microsoft는 이러한 문제를 해결할 수 있는 핫픽스를 제공하고 있습니다. 자세한 내용은 하기에 첨부한 링크를 참고해주시기 바랍니다.

    https://support.microsoft.com/en-us/kb/886695
    You receive an "Error 1053: The service did not respond to the start or control request in a timely fashion" error message when a service that uses the local system account tries to start on a Windows Server 2003-based computer

    [참고] 2015년 7월 14일 이후 Windows Server 2003에 대한 기술 지원이 종료되었으므로 이 점 참고해주시면 감사하겠습니다.


    2015년 10월 13일 화요일 오전 7:21
    중재자
  • 답변에 우선 감사 드립니다.

    해당 부분은 2003 서버에서는 정상적일 것이다.

    다만 2012 서버 스탠다아드 버전에서 해당 핫픽스를 설치가 되지 않았습니다.

    호환성에 문제로 말이죠.. 하드웨어나 운영체제의 호환성 문제인 듯 합니다.

    다음은 소스의 일부분입니다.


    //unsigned int __stdcall TTSGW_Server_Process(void *data)
    UINT TTSGW_Server_Process(LPVOID data)
    {
    CDASAM_TTSService *pThis = (CDASAM_TTSService *)data;
    WSADATA wsaData;
    struct sockaddr_in server_addr; //소켓 구조체
    struct sockaddr_in cli_addr; //클라이언트와 연결 시 클라이언트의 정보를 받아올 구조체를 정의합니다.
    int size = sizeof(cli_addr); //구조체의 크기를 정의합니다.

    int nSvr_Port = 0;
    char szSvr_IP[15 + 1] = { 0x00, };
    char ipv4_addr[16] = { 0x00, };

    fd_set    readfds, exceptfds;

    char ExeFileName[2048 + 1] = { 0x00, };

    ::GetModuleFileName(NULL, ExeFileName, 2048);
    int nIndex = RightIndex(ExeFileName, "\\");

    ExeFileName[nIndex] = 0x00;

    char IniPath[2048 + 1] = { 0x00, };
    sprintf(IniPath, "%s\\%s", ExeFileName, PARAINI);
    xprintf("IniPath :(%s)", IniPath);

    if (WSAStartup(WINSOCK_VERSION, &wsaData) != 0)
    {//
    xprintf("WSAStartup 실패, 에러 코드 = %d ", WSAGetLastError());
    return -1;
    }

    FD_ZERO(&readfds);
    FD_ZERO(&exceptfds);


    pThis->cs_initialized = FALSE;
    pThis->TTS_cs_initialized = FALSE;

    //// 서비스 등록 전에는 아래 로직 구동 되지 않는다.
    //// 서비스 시작하게 되면 위 로직은 건너 띄고, 아래 로직을 타게 된다.
    //// 서비시 재시작, 중지한 후 시작 할 경우에 해당한다.
    pThis->m_TTSMsgMap.RemoveAll();
    xprintf(_T("_tmain pThis->m_TTSMsgMap.RemoveAll()"));

    TTS_SPK_ID spkId;
    pThis->m_TTSSpk.RemoveAll();
    xprintf(_T("_tmain pThis->m_TTSSpk.RemoveAll()"));
    /*
    TTS_JUNWOO_DB(3) 준우(한국어, 남성)
    TTS_SUJIN_DB(8) 수진(한국어, 여성)
    TTS_YUMI_DB(10) 유미(한국어, 여성)
    */
    memset((void*)&spkId, 0x00, sizeof(spkId));
    memcpy(spkId.szSpkId, "TTS_JUNWOO_DB", sizeof(spkId.szSpkId) - 1);
    spkId.nSpkId = TTS_JUNWOO_DB;
    memcpy(spkId.szSpkDec, " 준우(한국어, 남성)", sizeof(spkId.szSpkDec) - 1);
    spkId.nSex = 1;
    pThis->m_TTSSpk.SetAt(spkId.szSpkId, spkId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void*)&spkId, 0x00, sizeof(spkId));
    memcpy(spkId.szSpkId, "TTS_SUJIN_DB", sizeof(spkId.szSpkId) - 1);
    spkId.nSpkId = TTS_SUJIN_DB;
    memcpy(spkId.szSpkDec, "수진(한국어, 여성)", sizeof(spkId.szSpkDec) - 1);
    spkId.nSex = 0;
    pThis->m_TTSSpk.SetAt(spkId.szSpkId, spkId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void*)&spkId, 0x00, sizeof(spkId));
    memcpy(spkId.szSpkId, "TTS_YUMI_DB", sizeof(spkId.szSpkId) - 1);
    spkId.nSpkId = TTS_YUMI_DB;
    memcpy(spkId.szSpkDec, "유미(한국어, 여성)", sizeof(spkId.szSpkDec) - 1);
    spkId.nSex = 0;
    pThis->m_TTSSpk.SetAt(spkId.szSpkId, spkId);// 복제를 넣기에 같은 변수이어도 된다.

    /*
    TTS_GYURI_DB(11) 규리(한국어, 여성)
    TTS_DAYOUNG_DB(12) 다영(한국어, 여성)
    TTS_CHORONG_DB(13) 초롱(한국어, 여성)
    TTS_HYERYUN_DB(14) 혜련(한국어, 여성)
    TTS_HYUNA_DB(15) 현아(한국어, 여성)
    TTS_JIMIN_DB(17) 지민(한국어, 여성)
    TTS_JIHUN_DB(18) 지훈(한국어, 남성)
    TTS_SENA_DB(19) 세나(한국어, 여성)
    TTS_YURA_DB(20) 유라(한국어, 여성)
    TTS_MARU_DB(21) 마루(한국어, 남성)
    TTS_KATE_DB(100) Kate(영어, 여성)
    TTS_PAUL_DB(101) Paul(영어, 남성)
    TTS_JULIE_DB(103) Julie(영어, 여성)
    TTS_JAMES_DB(104) James(영어, 남성)
    TTS_ASHLEY_DB(105) Ashley(영어, 여성)
    TTS_LILY_DB(200) Lily(중국어, 여성)
    TTS_WANG_DB(201) Wang(중국어, 남성)
    TTS_HUI_DB(202) Hui(중국어, 여성)
    TTS_LIANG_DB(203) Liang(중국어, 남성)
    TTS_HONG_DB(204) Hong(중국어, 여성)
    TTS_QIANG_DB(205) Qiang(중국어, 남성)
    TTS_MIYU_DB(300) Miyu(일본어, 여성)
    TTS_SHOW_DB(301) Show(일본어, 남성)
    TTS_MISAKI_DB(302) Misaki(일본어, 여성)
    TTS_HARUKA_DB(303) Haruka(일본어, 여성)
    TTS_SAYAKA_DB(304) Sayaka(일본어, 여성)
    TTS_RYO_DB(305) Ryo(일본어, 남성)
    TTS_HIKARI_DB(306) Hikari(일본어, 여성)
    TTS_TAKERU_DB(307) Takeru(일본어, 남성)
    TTS_RISA_DB(308) Risa(일본어, 여성)
    TTS_AKIRA_DB (309) Akira (일본어, 남성)
    TTS_ERICA_DB (310) Erica (일본어, 여성)
    TTS_VIOLETA_DB (400) Violeta (스페인어, 여성)
    TTS_FRANCISCO_DB (401) Francisco (스페인어, 남성)
    TTS_GLORIA_DB (402) Gloria (스페인어, 여성)
    TTS_BRIDGET_DB (500) Bridget (영국식영어, 여성)
    TTS_HUGH_DB (501) Hugh (영국식영어, 남성)
    TTS_CHLOE_DB (600) Chloe (캐나다-불어, 여성)*/

    TTS_FORMAT ttsFormatId;
    pThis->m_TTSFormatMap.RemoveAll();
    xprintf(_T("_tmain m_TTSFormatMap.RemoveAll()"));

    /*  FORMAT_DEFAULT(0) Default(서버에서 설정한 기본 포맷)
    FORMAT_WAV(1) 16bit linear PCM Wave
    FORMAT_PCM(2) 16bit linear PCM
    FORMAT_MULAW(3) 8bit Mu - law PCM
    FORMAT_ALAW(4) 8bit A - law PCM
    FORMAT_ADPCM(5) 4bit Dialogic ADPCM
    FORMAT_ASF(6) Windows ASF
    FORMAT_OGG(10) Ogg VorbisOnStart
    FORMAT_8BITWAV(11) 8bit unsigned linear PCM Wave
    FORMAT_AWAV(12) 8bit A - law PCM Wave
    FORMAT_MUWAV(13) 8bit Mu - law PCM Wave
    FORMAT_OUTPROC(17) User defined Format
    */
    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_DEFAULT", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_DEFAULT;
    memcpy(ttsFormatId.szFormatDec, "Default(서버에서 설정한 기본 포맷)", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "wav", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_WAV", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_WAV;
    memcpy(ttsFormatId.szFormatDec, "16bit linear PCM Wave", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "wav", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.


    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_PCM", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_PCM;
    memcpy(ttsFormatId.szFormatDec, "16bit linear PCM", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "pcm", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_MULAW", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_MULAW;
    memcpy(ttsFormatId.szFormatDec, "8bit Mu - law PCM", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "pcm", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_ALAW", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_ALAW;
    memcpy(ttsFormatId.szFormatDec, "8bit A - law PCM", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "pcm", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_ADPCM", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_ADPCM;
    memcpy(ttsFormatId.szFormatDec, "4bit Dialogic ADPCM", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "vox", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_ASF", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_ASF;
    memcpy(ttsFormatId.szFormatDec, "Windows ASF", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "asf", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_OGG", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_OGG;
    memcpy(ttsFormatId.szFormatDec, "Ogg Vorbis", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "wav", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_8BITWAV", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_8BITWAV;
    memcpy(ttsFormatId.szFormatDec, "8bit unsigned linear PCM Wave", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "wav", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_AWAV", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_AWAV;
    memcpy(ttsFormatId.szFormatDec, " 8bit A - law PCM Wave", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "wav", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_MUWAV", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_MUWAV;
    memcpy(ttsFormatId.szFormatDec, "8bit Mu - law PCM Wave", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "wav", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    memset((void *)&ttsFormatId, 0x00, sizeof(ttsFormatId));
    memcpy(ttsFormatId.szFormatID, "FORMAT_OUTPROC", sizeof(ttsFormatId.szFormatID) - 1);
    ttsFormatId.nFormatId = FORMAT_OUTPROC;
    memcpy(ttsFormatId.szFormatDec, "User defined Format", sizeof(ttsFormatId.szFormatDec) - 1);
    memcpy(ttsFormatId.szExt, "wav", sizeof(ttsFormatId.szExt) - 1);
    pThis->m_TTSFormatMap.SetAt(ttsFormatId.szFormatID, ttsFormatId);// 복제를 넣기에 같은 변수이어도 된다.

    pThis->m_hSvr = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (pThis->m_hSvr == INVALID_SOCKET)
    {
    xprintf("소켓 생성 실패, 에러 코드 : %d ", WSAGetLastError());
    WSACleanup();
    //if (pThis->m_hThread) _endthreadex((unsigned int)pThis->m_hThread);
    return -1;
    }

    pThis->m_nMaxTTS = ::GetPrivateProfileInt("TTS", "TTSCH_CNY", 4, IniPath);
    CTTSClient **pTTSCli = (CTTSClient **)malloc(sizeof(CTTSClient *)*pThis->m_nMaxTTS);
    memset(pTTSCli, 0x00, sizeof(CTTSClient *)*pThis->m_nMaxTTS);

    pThis->m_TTSClientQueue.RemoveAll();
    for (int nRep = 0; nRep < pThis->m_nMaxTTS; nRep++)
    {
    pTTSCli[nRep] = new CTTSClient(nRep + 1);
    pThis->m_TTSClientQueue.AddTail(pTTSCli[nRep]);
    }

    pThis->m_nClient_Cnt = ::GetPrivateProfileInt("CLIENT", "CLIENT_CNY", 1, IniPath);
    nSvr_Port = ::GetPrivateProfileInt("SERVER", "PORT", 9000, IniPath);
    ::GetPrivateProfileString("SERVER", "IP", "127.0.0.1", szSvr_IP, sizeof(szSvr_IP), IniPath);
    xprintf("SERVER IP:(%s)", szSvr_IP);
    // 서버 포트 정보 지정
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(nSvr_Port);
    inet_pton(AF_INET, szSvr_IP, &(server_addr.sin_addr));//AF_INET6:IPv6 사용
    //server_addr.sin_addr.s_addr = 
    //inet_addr(szSvr_IP); ==> 전처리에 추가 _WINSOCK_DEPRECATED_NO_WARNINGS하여 사용
    // htonl(INADDR_ANY); 시스템에 활성화 된 LAN 카드의 IP 주소 모두 이용

    //// 지정된 서버 IP,PORT로 해당 소켓 핸들어에 연결 처리
    if (bind(pThis->m_hSvr, (struct sockaddr*)&server_addr, sizeof(server_addr)) == INVALID_SOCKET)
    {
    xprintf("bind() 실행 에러");
    pThis->m_hCli_Thread.RemoveAll();

    for (int nRep = 0; nRep < pThis->m_nMaxTTS; nRep++)
    {
    delete pTTSCli[nRep];
    pTTSCli[nRep] = NULL;
    }
    delete pTTSCli;
    pThis->m_TTSClientQueue.RemoveAll();

    pThis->m_TTSSpk.RemoveAll();
    pThis->m_TTSFormatMap.RemoveAll();
    pThis->m_TTSMsgMap.RemoveAll();
    if (pThis->m_hSvr) ::closesocket(pThis->m_hSvr);

    pThis->_win_delete_handler();
    pThis->IScenario_delete_handler();
    WSACleanup();
    //if (pThis->m_hThread) _endthreadex((unsigned int)pThis->m_hThread);
    return -1;
    }

    //-------------------------
    // 소켓의 IO 모드 지정 : FIONBIO
    // enables or disables the blocking mode for the 
    // socket based on the numerical value of iMode.
    // If ioctl_opt = 0, blocking is enabled; 
    // If ioctl_opt != 0, non-blocking mode is enabled.
    unsigned long ioctl_opt = 1;// 블록킹 가능 상태(0)
    if (ioctlsocket(pThis->m_hSvr, FIONBIO, &ioctl_opt) == SOCKET_ERROR) {
    xprintf("ioctlsocket failed %d", WSAGetLastError());
    pThis->m_hCli_Thread.RemoveAll();

    for (int nRep = 0; nRep < pThis->m_nMaxTTS; nRep++)
    {
    delete pTTSCli[nRep];
    pTTSCli[nRep] = NULL;
    }
    delete pTTSCli;
    pThis->m_TTSClientQueue.RemoveAll();

    pThis->m_TTSSpk.RemoveAll();
    pThis->m_TTSFormatMap.RemoveAll();
    pThis->m_TTSMsgMap.RemoveAll();
    if (pThis->m_hSvr) ::closesocket(pThis->m_hSvr);

    pThis->_win_delete_handler();
    pThis->IScenario_delete_handler();
    WSACleanup();
    //if (pThis->m_hThread) _endthreadex((unsigned int)pThis->m_hThread);
    }

    if (listen(pThis->m_hSvr, (pThis->m_nClient_Cnt * 2)) == INVALID_SOCKET)
    {
    printf("대기상태 모드 설정 실패n");

    for (int nRep = 0; nRep < pThis->m_nMaxTTS; nRep++)
    {
    delete pTTSCli[nRep];
    pTTSCli[nRep] = NULL;
    }
    delete pTTSCli;
    pThis->m_TTSClientQueue.RemoveAll();

    pThis->m_TTSSpk.RemoveAll();
    pThis->m_TTSFormatMap.RemoveAll();
    pThis->m_TTSMsgMap.RemoveAll();
    if (pThis->m_hSvr) ::closesocket(pThis->m_hSvr);

    pThis->_win_delete_handler();
    pThis->IScenario_delete_handler();
    WSACleanup();
    //if (pThis->m_hThread)  _endthreadex((unsigned int)pThis->m_hThread);
    return -1;
    }


    /* 센드 버퍼와 리시브 버퍼의 최대 크기 지정 할수도 있다.

    bsize = bsize * 2;
    setsockopt(s, SOL_SOCKET, SO_SNDBUF, &bsize, (socklen_t)rn);

    bsize = bsize * 2;
    setsockopt(s, SOL_SOCKET, SO_RCVBUF, &bsize, (socklen_t)rn);

    getsockopt(...);// 위와 반대로 기 설정된 값들을 가지고 온다/
    */


    FD_SET(pThis->m_hSvr, &readfds);
    FD_SET(pThis->m_hSvr, &exceptfds);

    SOCKET h_CliTmp = 0;

    //Map 초기화
    pThis->m_hCli_Thread.RemoveAll();

    int ret = 0;
    while (pThis->m_bRun)
    {
    pThis->_win_enter_handler();
    if (pThis->m_nClient_Cnt > 0 && pThis->m_nClient_Cnt < pThis->m_hCli_Thread.GetSize())
    {
    xprintf("지정된 클라이언트 개수를 초과하여, 접속 시도 하였습니다.");
    }
    pThis->_win_leave_handler();
    //넌 블록킹 모드를 직접 블록킹 모드 화 하여 개발...
    xprintf("접속 대기중...");
    ret = select(pThis->m_hSvr + 1, &readfds, NULL, &exceptfds, NULL);// 읽기 버퍼와 쓰기 버퍼으로부터 
    if (ret == SOCKET_ERROR) {
    xprintf("select failed %d", WSAGetLastError());
    }
    if (ret == 0){
    xprintf("Select returned no fds ready");
    }

    //리스닝 포트 셋팅
    if (FD_ISSET(pThis->m_hSvr, &readfds)){

    // 대기형 소켓으로 지정 한다.(서버)
    // 두번째 인자: 대기 큐의 최대 개수
    // 동접수와는 다른 개념임.. (비숫)

    // 실제 접속 대기 한다.
    // 접속  허용이 될 경우, 해당 클라이언트의  IP 주소, 소켓 핸들 등을 획득 한다.
    h_CliTmp = accept(pThis->m_hSvr, (struct sockaddr*)&cli_addr, &size);
    if (h_CliTmp == INVALID_SOCKET && pThis->m_bRun == 0) break;
    else if (h_CliTmp == INVALID_SOCKET)
    {
    xprintf("accept failed %d", WSAGetLastError());
    continue;
    }

    pThis->_win_enter_handler();

    TTSGw_Client *pGwCli = new TTSGw_Client;

    pGwCli->pThis = pThis;
    pGwCli->hClient = h_CliTmp;

    HANDLE h_cliThread = 0;
    h_cliThread = (HANDLE)_beginthreadex(NULL, 0, TTSGW_Client_Process, (LPVOID)(pGwCli), 0, &(pThis->m_threadID));// 해당 부분 주석 처리 하면 문제가 없다.(서비스)
    pThis->m_hCli_Thread.SetAt(h_CliTmp, h_cliThread);
    pThis->_win_leave_handler();
    }
    }

    pThis->m_hCli_Thread.RemoveAll();

    for (int nRep = 0; nRep < pThis->m_nMaxTTS; nRep++)
    {
    delete pTTSCli[nRep];
    pTTSCli[nRep] = NULL;
    }
    delete pTTSCli;
    pThis->m_TTSClientQueue.RemoveAll();

    pThis->m_TTSSpk.RemoveAll();
    pThis->m_TTSFormatMap.RemoveAll();
    pThis->m_TTSMsgMap.RemoveAll();
    if (pThis->m_hSvr)
    {
    ::closesocket(pThis->m_hSvr);
    pThis->m_hSvr = NULL;
    }

    pThis->_win_delete_handler();
    pThis->IScenario_delete_handler();
    WSACleanup();
    //if (pThis->m_hThread) _endthreadex((unsigned int)pThis->m_hThread);
    return 0;
    }

    2015년 10월 14일 수요일 오전 7:52
  • 해당 소스는 쓰레드 입니다.

    OnStarted에서 위 스레드를 생성 합니다.

     

    void CDASAM_TTSService::OnStarted(){
    xprintf("CUpdateService::OnStarted"); 
    //m_hThread = (HANDLE)_beginthreadex(NULL, 0, TTSGW_Server_Process, (LPVOID)(this), 0, &(m_threadID));
    _thread = AfxBeginThread(TTSGW_Server_Process, (LPVOID)(this)); //==> 이 메인 스레드만 생성 시에는

    문제가 없었습니다. }

    void CDASAM_TTSService::OnStopped(){
    xprintf("CDASAM_TTSService::OnStopped");

    DWORD dwExitCode;
    if (m_hSvr)
    {
    SOCKET hSvr = m_hSvr;
    m_hSvr = NULL;
    m_bRun = 0;//메인 쓰레드의 루핑을 빠져 나오게 한다.
    ::closesocket(hSvr);
    }

    if (_thread && _thread->m_hThread)
    {
    ::WaitForSingleObject(_thread->m_hThread, INFINITE);
    GetExitCodeThread(m_hThread, &dwExitCode);
    m_hThread = NULL;
    }
    }

    2015년 10월 14일 수요일 오전 7:54
  • 다만 TTSGW_Client_Process 스레드를 생성하도록  하면 ( 생성 함수:AfxBeginThread 로도 해 보았습니다.)

    해당 스레드는 소켓 접속 시에만 생성 합니다.

    따라서 서비스 시작 시에는 하나만 합니다.

    그럼에도 불루하고...

    릴리즈 모드로 컴파일 후 서비스 등록 하고 나서...

    서비스 시작 하려면 1053 오류가 나온다는 것입니다.

    2015년 10월 14일 수요일 오전 7:56