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
[50912] Re:소켓쓰레드에서 에러가 발생합니다. 소스에서 에러가 무슨 원인인지 부탁드립니다.
장성호 [nasilso] 3494 읽음    2007-10-16 19:28
보통 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         답변감사합니다. 참조링크까지...^^ 짱구오빠 2826 2007/10/17
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.