C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[50915] 답변감사합니다. 참조링크까지...^^
짱구오빠 [saonara] 2825 읽음    2007-10-17 10:33
장성호 님이 쓰신 글 :
: 보통 Socket이 Close될때 Client , Server간에 서로 close하겠다고
: 정보를 주고 받고  close하는게 정상적인 close인데...
:
: Client에서 그런 정보를 보내지 못하고 끊어지면  위와같은 에러가 뜨는것 같습니다.
:
:    예를 들어  - 네트워크가 갑자기 끊어지거나
:                    - Client프로그램이 갑자기 죽거나 등등의 현상이 발생하면
:    
:
: 제대로된 해결은 아닌것 같은데..
: 그냥 Read부분에 try ~ catch 로 잡으시면 될듯 합니다.
:
:              try
:                 {
:                     int rslt=pStream->Read(Buffer, 100);
:                     if( rslt== 0)
:                     {
:                         // 입력된 값이 없으면 종료
:                         HIndex=fmServer->cbSocketHandle->Items->IndexOf(IntToStr(ClientSocket->SocketHandle));
:                         fmServer->cbSocketHandle->Items->Delete(HIndex);
:                         if(fmServer->cbSocketHandle->Items->Count==0)
:                         {
:                             fmServer->cbSocketHandle->Text="연결된 소켓 없음";
:                         }
:
:                         ClientSocket->Close();
:                     }
:
:                     fmServer->mbChat->Lines->Add(String(Buffer));
:                     fmServer->BroadCastOut(String(Buffer));
:                     fmServer->edtActiveThread->Text=fmServer->ServerSocket1->Socket->ActiveThreads;
:                 }
:                 catch(...)
:                 {
:                     // 입력된 값이 없으면 종료
:                     HIndex=fmServer->cbSocketHandle->Items->IndexOf(IntToStr(ClientSocket->SocketHandle));
:                     fmServer->cbSocketHandle->Items->Delete(HIndex);
:                     if(fmServer->cbSocketHandle->Items->Count==0)
:                     {
:                         fmServer->cbSocketHandle->Text="연결된 소켓 없음";
:                     }
:
:                     ClientSocket->Close();
:                 }
:
: //------------------------------------------
: 구글신에 의지하여 TServerClientThread   예제 수십개를 보았지만
: 대부분 아래와 같은 처리하더군요
: 예외는 HandleException();  으로...
:
:
:   void   __fastcall   TMyServerThread::ClientExecute()  
:   {  
:       while   (!Terminated   &&   ClientSocket->Connected)   //   make   sure   connection   is   active  
:       {  
:           try  
:           {  
:               TWinSocketStream   *pStream   =   new   TWinSocketStream(ClientSocket,   60000);  
:               try  
:               {  
:                   char   buffer[50];  
:                   memset(buffer,   0,   sizeof(buffer));  
:                   if   (pStream->WaitForData(6000))   //   give   the   client   60   seconds   to   start   writing  
:                   {  
:    
:                       if   (pStream->Read(buffer,   sizeof(buffer))   ==   0)  
:                           ClientSocket->Close();   //   if   can't   read   in   60   seconds,   close   the   connection  
:                                     //   now   process   the   request  
:                   }  
:                   else  
:                       ClientSocket->Close();  
:               }  
:               __finally  
:               {  
:                   delete   pStream;  
:               }  
:           }  
:           catch   (...)  
:           {  
:             HandleException();  
:           }  
:       }  
:   }  
:
: 참고 하세요
: http://dn.codegear.com/article/26276
: http://topic.csdn.net/t/20060704/23/4860640.html
: http://duketown.com/marcel/server.shtml
: http://www.delmadang.com/cwb-bin/CrazyWWWBoard.exe?mode=read&num=754&page=49&db=dmdlec3&backdepth=3
: http://topic.csdn.net/t/20020304/19/554711.html
: http://delphi.newswhat.com/geoxml/forumhistorythread?groupname=borland.public.delphi.internet.winsock&messageid=40863a71@newsgroups.borland.com
: http://www.ipc.hokusei.ac.jp/~z00104/delphi/thread.html
: http://book.77169.org/ask1/ask100852.htm
: http://forum.sources.ru/index.php?showtopic=159584
:
:
:
: 그럼..
:   
:    
:   
:
: 짱구오빠 님이 쓰신 글 :
: : Project SocketTread.exe raised exception class ESocketErrro with message 'Read error
: : 64, 지정된 네트워크 이름을 더 이상 사용할 수 없습니다.'. Process stopped. Use Step or Run
: : to Continue.
: :
: : 이런 메시지가 뜹니다.
: :
: : void __fastcall TServerSocketThread::ClientExecute(void)
: : 함수에서
: : if(pStream->WaitForData(300000))
: : 에서 기다리다가 소켓으로 수신되면
: : if(pStream->Read(Buffer, 100) == 0)를 처리한 후
: : 정상적으로 처리된 후
: : 다시
: : if(pStream->WaitForData(300000)) 부분에서
: : 수신을 기다려야 하는데
: : if(pStream->Read(Buffer, 100) == 0)으로 넘아간 후
: : pStream->Read 함수 처리시
: : 위와같은 에러메시지가 나옵니다.
: :
: : 버퍼의 내용이 클리어가 않된건지...
: :
: : 아래 소스는 자료실에 있는 소켓쓰레드를 옮겨서 코딩한 겁니다.
: : 무슨 에러인지 모르겠네요.
: :
: : 그리고 소켓서버의 멀티 쓰레드는 아래와 같이 코딩하면 되는건가요?
: :
: : 도와주세요.
: :
: :
: :
: : 소스 내용입니다.
: :
: : __fastcall TServerSocketThread::TServerSocketThread(bool CreateSuspended, TServerClientWinSocket * ASocket)
: :     : TServerClientThread(CreateSuspended, ASocket)
: : {
: :         FreeOnTerminate=true;
: : }
: :
: : void __fastcall TServerSocketThread::ClientExecute(void)
: : {
: :     int HIndex;
: :     TWinSocketStream *pStream;                             // 소켓을 스트림으로 받음
: :     char Buffer[100];
: :
: :     memset(Buffer, 0x00, sizeof(Buffer));
: :
: :     while (!Terminated && ClientSocket->Connected)
: :     {
: :         pStream = new TWinSocketStream(ClientSocket, 60000);
: :         try
: :         {
: :             memset(Buffer, 0, sizeof(Buffer));
: :             if(pStream->WaitForData(300000))
: :             {
: :                 // 5분간 입력이 없으면 종료
: :                 if(pStream->Read(Buffer, 100) == 0)
: :                 {
: :                     // 입력된 값이 없으면 종료
: :                     HIndex=fmServer->cbSocketHandle->Items->IndexOf(IntToStr(ClientSocket->SocketHandle));
: :                     fmServer->cbSocketHandle->Items->Delete(HIndex);
: :                     if(fmServer->cbSocketHandle->Items->Count==0)
: :                     {
: :                         fmServer->cbSocketHandle->Text="연결된 소켓 없음";
: :                     }
: :
: :                     ClientSocket->Close();
: :                 }
: :
: :                 fmServer->mbChat->Lines->Add(String(Buffer));
: :                 fmServer->BroadCastOut(String(Buffer));
: :                 fmServer->edtActiveThread->Text=fmServer->ServerSocket1->Socket->ActiveThreads;
: :             }
: :             else
: :             {
: :                 HIndex=fmServer->cbSocketHandle->Items->IndexOf(IntToStr(ClientSocket->SocketHandle));
: :                 fmServer->cbSocketHandle->Items->Delete(HIndex);
: :                 if(fmServer->cbSocketHandle->Items->Count==0) fmServer->cbSocketHandle->Text="연결된 소켓 없음";
: :                 ClientSocket->Close();
: :             }
: :         }
: :         __finally
: :         {
: :             delete pStream;
: :         }
: :     }
: :
: :     //종료시 cbSocketHandle에서 ClientSocketHandle 삭제
: :     HIndex=fmServer->cbSocketHandle->Items->IndexOf(IntToStr(ClientSocket->SocketHandle));
: :     fmServer->cbSocketHandle->Items->Delete(HIndex);
: :     if(fmServer->cbSocketHandle->Items->Count==0)
: :     {
: :         fmServer->cbSocketHandle->Text="연결된 소켓 없음";
: :     }
: : }
: :
: :
: :
: :
: : //---------------------------------------------------------------------------
: :
: : //      쓰레드 외부에서 ClientSocketHandle값으로 CustomWinSocket을 생성하여 접속한 각 클라이언트로
: : //      데이타를 날려준다.  - BroadCast
: : void __fastcall TfmServer::BroadCastOut(String SendString)
: : {
: :     for(int i=0; i<cbSocketHandle->Items->Count;i++)
: :     {
: :         TCustomWinSocket *CustomWinSocket = new TCustomWinSocket(StrToInt(cbSocketHandle->Items->Strings[i]));
: :         CustomWinSocket->SendText(SendString);
: :         //      delete CustomWinSocket;
: :     }
: : }
: :
: :
: : //---------------------------------------------------------------------------
: :
: : void __fastcall TfmServer::FormCreate(TObject *Sender)
: : {
: :     ServerSocket1->Port=2000;
: :     ServerSocket1->Open();
: :     Sleep(100);
: :     Application->ProcessMessages();
: :     cntNum=0;
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TfmServer::ServerSocket1ClientDisconnect(TObject *Sender,
: :       TCustomWinSocket *Socket)
: : {
: :     mbStat->Lines->Add("사용자가 접속을 종료했습니다.");
: :     cntNum--;
: :     edtTotalNum->Text=cntNum;
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TfmServer::ServerSocket1Accept(TObject *Sender,
: :       TCustomWinSocket *Socket)
: : {
: :     mbStat->Lines->Add("사용자가 접속했습니다.");
: :     cntNum++;
: :     edtTotalNum->Text=cntNum;
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TfmServer::ServerSocket1GetThread(TObject *Sender,
: :       TServerClientWinSocket *ClientSocket,
: :       TServerClientThread *&SocketThread)
: : {
: :     // TServerClientThread 를 생성
: :     SocketThread = new TServerSocketThread(false, ClientSocket);
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TfmServer::ServerSocket1GetSocket(TObject *Sender,
: :       int Socket, TServerClientWinSocket *&ClientSocket)
: : {
: :     // SocketHandle을 저장
: :     cbSocketHandle->Items->Add(IntToStr(Socket));
: :     if(cbSocketHandle->Items->Count==1)
: :     {
: :         cbSocketHandle->Text=IntToStr(Socket);
: :     }
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TfmServer::FormClose(TObject *Sender, TCloseAction &Action)
: : {
: :     //Server Socket Close
: :     ServerSocket1->Close();
: :
: :     //Memory Free
: :     Action = caFree;
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TfmServer::ServerSocket1ThreadEnd(TObject *Sender,
: :       TServerClientThread *Thread)
: : {
: :     edtActiveThread->Text=fmServer->ServerSocket1->Socket->ActiveThreads;
: :    
: : }
: : //---------------------------------------------------------------------------
: : void __fastcall TfmServer::ServerSocket1ClientError(TObject *Sender,
: :       TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
: : {
: :     mbStat->Lines->Add("사용자의 서버에 문제가 있습니다.");
: : }

+ -

관련 글 리스트
50908 소켓쓰레드에서 에러가 발생합니다. 소스에서 에러가 무슨 원인인지 부탁드립니다. 짱구오빠 2108 2007/10/16
50912     Re:소켓쓰레드에서 에러가 발생합니다. 소스에서 에러가 무슨 원인인지 부탁드립니다. 장성호 3494 2007/10/16
50915         답변감사합니다. 참조링크까지...^^ 짱구오빠 2825 2007/10/17
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.