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

C++빌더 강좌/문서
C++Builder Programming Tutorial&Docments
[28] C++Builder Socket 분석 (5) - Socket에서 Error 처리
정남영 [kermi] 13872 읽음    2002-04-26 03:43

5. Socket에서 Error 처리

작성자 : 정남영(kermi)
E-mail : kermi@borlandforum.com 

 

0. 강의에 들어가면서

 

1. Socket Class의 구조

 

2. Socket이 접속할 때

 

3. Socket이 종료될 때

 

4. Socket에 Data가 전달될 때

Þ

5. Socket에서 Error 처리

 

Borland Socket은 소켓을 이용하여 작업을 처리하는 도중 문제가 발생하게 되면 항상 OnError 이벤트를 발생하게 된다. 특히 TserverSocket의 경우엔 수많은 TserverClientWinSocket의 모든 에러메세지를 TserverSocket의 OnClientError에서 수신받을수 있다. OnClientError 이벤트가 발생할땐 넘어오는 파라메터중 다음의 3가지에 대해서 알아보도록 하자.

Socket: TcustomWinSocket

ErrorEvent: TerrorEvent

var ErrorCode: Integer

 Socket은 문제가 발생한 소켓의 포인터이다. ErrorEvent는 어떠한 작업을 진행하다가 에러가 발생했는지를 알려주게 된다. 만약 값이 eeSend 라면 Send를 하기 위해 작업을 진행하다가 에러가 발생했다는 것이 된다. 마지막으로 ErrorCode는 GetLastError를 이용하여 얻어낸 에러 코드이다. 에러코드는 코드 번호에 따라 오류 내용이 서술되어 있으며 자세한 내용은 Winsock 관련서적을 참고하거나 MSDN을 참고하면 자세한 정보를 얻을수 있다. 특히 Errorcode의 경우엔 Code값을 0으로 설정해 주지 않으면 오류번호를 가진 메시지 박스가 화면에 뜨게 되므로 원만한 서버의 운영을 위해선 반드시 ErrorCode를 0으로 설정해주어야 한다.

 대부분의 사용자들은 에러이벤트를 다음과 같이 처리한다.

void __fastcall TfrmMain::ServerSocketClientError(TObject *Sender,
      TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
    String Temp;
    Temp.printf("수신 Socket Error -> ErrorCode : %d", ErrorCode);
    Memo->Lines->Add(Temp);
    /****************************
      ErrorCode에 해당하는 적절한 대응책을 구현
    ****************************/
    ErrorCode = 0;
    Socket->Close(); // Error가 발생한 Socket을 닫음
}

 

위의 내용은 만약 TserverClientWinSocket에서 문제가 발생하면 ErrorCode를 0으로 설정하고 Socket을 닫는것이다. Socket->Close()를 진행하게 되면 OnClientDisconnect 이벤트가 발생하게 되며 최종적으로 처리를 진행하게 된다. 그렇다면 만약 OnClientDisconnect에서 Socket이 종료될 때 에러가 발생해서 종료한것인지 아니면 정상적인 처리에 의해서 종료한 것인지를 확인할려면 어떻게 해야 될까? 답은 간단하다. OnClientError이벤트에서 에러가 발생한 소켓이 어떤놈이라는걸 확인시켜주면 된다. 그리고 OnClientDisconnect에서 종료되는 소켓이 에러가 발생했던 소켓인지 아닌지를 확인하면 되는것이다.

그림으로 보도록 하자.

 하지만 대단히 불편한 문제가 발생한다. 바로 Flag를 어디에 두어야 하는가이다. 동적으로 Client의 개수가 변경되기 때문에 유동적인 클라이언트의 수에 대응할수 있는 자료구조인  Tlist정도는 사용하여야 한다. 하지만 겨우 Flag를 설정하기 위해 사용하기엔 작업량이 많아지게 된다. 또 만약 각각의 소켓에 사용자 정보를 저장해야 될 경우가 있다면 어떻게 할것인가? 앞에서 언급한 Tlist를 이용하여 구현하게 되면 많은 작업을 해야 된다. TcustomWinSocket에서는 이러한 문제를 해결하기 위해 Data라는 Property를 제공한다. Data는 void * 를 대입받는다.

 즉 필요한 메모리 공간을 new를 이용하여 동적으로 할당한후 내용을 입력하고 Socket->Data에 대입을 하면 해당소켓의 부가적인 정보를 편하게 관리할수 있게 된다.

class UserInfo
{
    String Name;   // 사용자 이름저장
    DWORD Flag;    // 0 이면 정상종료, 1 이면 에러 발생 후 종료
};

void __fastcall TfrmMain::ServerSocketClientConnect(TObject *Sender,
 TCustomWinSocket *Socket)
{
    UserInfo* pUserInfo = new UserInfo;
    pUserInfo->Flag = 0;
    Socket->Data = pUserInfo;
}

void __fastcall TfrmMain::ServerSocketClientError(TObject *Sender,
      TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)
{
    ((UserInfo*)Socket->Data)->Flag = 1;    // Error 설정
/****************************
      ErrorCode에 해당하는 적절한 대응책을 구현
    ****************************/
    ErrorCode = 0;
    Socket->Close(); // Error가 발생한 Socket을 닫음
}

void __fastcall TfrmMain::ServerSocketClientDisconnect(TObject *Sender,
 TCustomWinSocket *Socket);
{
    if (((UserInfo*)Socket->Data)->Flag == 0)
       Memo->Lines->Add(((UserInfo*)Socket->Data)->Name + "정상적인 종료");
    else
       Memo->Lines->Add(((UserInfo*)Socket->Data)->Name + "에러발생 종료");
}

 

  이상으로 그동안 연재했던 강좌를 끝내도록 하겠습니다(강좌도 끝났으니 이젠 말 높여야 겠죠 ? ^^;;). 정말 많이 아쉽기만 하네요. 그동안 게으름 피웠던 부분들과 내용도 처음 의도했던 것보다 부실해서 많은 후회가 되기도 합니다. 기회가 되면 IOCP에 관련된 내용도 강좌를 해보고 싶지만 강좌 연재가 생각보다 어려운 작업임을 이번기회를 통해 알게 되었습니다.

 그동안 내용이 매끄럽지 못하고 많이 부족한 글을 읽어준 독자들께도 정말 감사합니다. 중간에 강의가 너무 오랫동안 올라가지 못한 점도 정말 죄송할 따름이구요..(그동안 개인적인 사정이 너무 많어서욤.. ^^;;)

 앞으로도 볼랜드 포럼에서 계속 활동할 예정입니다. 회사가 볼랜드 제품을 사용하지 않다 보니 빌더6나 델파이6는 아직 제대로 접해보지 못했습니다. 넘 안타까운 현실입니다. 그래서 Q&A에 올라오는 질문도 인디소켓에 관련된 내용은 제가 못할 것 같구요.. winsock에 관련된 내용은 답변을 달도록 열심히 노력하겠습니다.

 

김성진.kark [kark]   2002-05-21 00:08 X
정말 수고하셨습니다. 재밌게 읽었답니다.

+ -

관련 글 리스트
28 C++Builder Socket 분석 (5) - Socket에서 Error 처리 정남영 13872 2002/04/26
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.