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
[62051] Re:(인디사용)소켓통신시 에러처리 방법 문의드립니다.
땅주인 [heaven2] 2378 읽음    2010-07-29 18:03
인디컴포넌트를 쓰지 않아서 정확한 답변이 아닐 지는 모르겠지만... 소켓의 일반적인 운용에 대해서는
답을 드릴 수 있을 것 같아 몇 자 적어봅니다.

newhuni 님이 쓰신 글 :
: Indy컴포넌트를 이용하여 서버-클라이언트를 구성하였습니다.
: Server1 : Client1의 통신에서는 정상적으로 동작합니다.
: 그런데 Server1 : Client(n)의 통신시 동작중에 " WSAENOBUFS (10055) No buffer space available. "
: 에러 메시지가 발생합니다.
:
: 메시지를 보면 사용가능한 버퍼 공간이 부족하다는 뜻인데...
:
: 1)
: Server와 Client의 통신 데이타는 한번에 150바이트가 넘지 않습니다.
: 그리고 RecvBufferSize, SendBufferSize의 경우 모두 32768입니다.
: 이 정도면 상당히 큰 사이즈 아닌가요??
: 버퍼 사이즈를 늘려야 한다면 어떤 함수를 사용해야 하나요?

버퍼 사이즈가 부족하다기 보다 수신된 데이터를 가져가지 않아 수신 버퍼가 꽉 찰때까지
쌓이는 것으로 보입니다. 보통 윈도우 소켓의 수신 버퍼는 4K정도 되는데..이정도면 어지간한 수신 데이터를
다 처리하거든요. 쌓인다고 볼 수 있습니다.

:
: 2)
: 해당 오류발생시 처리 방법이 궁금합니다.
: 아래의 서버 예외처리 함수에서 처리하면 되는건가요??
: void __fastcall TMainForm::IdTCPServerException(TIdPeerThread *AThread,
:       Exception *AException)
: {       
:                 int ErrorCode = ((EIdSocketError *)AException)->LastError;
:                 if(ErrorCode == 10055)
:                {
:                      // 해당 클라이언트 쓰레드의 송/수신 버퍼를 클리어하고
:                      // 에러코드를 0으로 초기화한다...
:                }
: }
:
: 3)
: 아래 코드는 클라이언트로부터 패킷을 수신 받는 루틴입니다.
: 각 클라이언트의 통신 쓰레드가 인수로 전달된 AThread로 알고있습니다.
: 그렇다면 여러개의 클라이언트와 통신할 때 아래의 buf변수는 어떻게 되나요?
: buf는 클라이언트에 하나씩 있어야 하는데...
: 아래와 같이 코딩하면 여러 클라이언트에서 독립적으로 buf변수를 사용하게 되나요?
:
: (클라이언트로부터 데이타 받은 뒤 정상데이타라면 해당 명령에 따라 클라이언트에 데이타를 전송한다.)
: void __fastcall TMainForm::IdTCPServerExecute(TIdPeerThread *AThread)
: {   
:    unsigned char buf[MAX_PACKET] = {0,};
:
:    try
:    {
:          AThread->Connection->ReadBuffer(buf, MAX_PACKET);
:    }catch(...){}
:
:    // Check Check Sum
:    unsigned int CheckSum = buf[0] + buf[1] + buf[2] + buf[3] + buf[4] + buf[5];
:    if( CheckSum != (unsigned int)((buf[6]<<8) | buf[7]) ) return;
:
:    // Make Tx Packet
:    SendTx();
:    //----------------------------------------------------------------------//
: }

각 소켓마다 수신 버퍼가 있고, 위와 같이 수신된 데이터를 읽는다면, 여러 소켓의 데이터가
섞일 가능성이 있습니다. Sender 쪽에서 150byte를 보냈다고 해서 수신단에 한 번에 150byte가
수신된다는 보장이 없거든요. Sender쪽에서 보낸 데이터가 여러 번에 걸쳐서 수신될 수 있는
가능성이 있으므로, 각 소켓마다 따로 수신 버퍼를 두거나(소켓이 가지고 있는 버퍼 말고)..
몇 개의 버퍼를 두어 한 프레임의 데이터가 모두 수신되었는 지를 확인하는 루틴이 필요합니다.

저의 경우 각 소켓마다 별도의 수신 버퍼를 두면 메모리 활용면에서 효율적이지 못하기에
적당한 객수의 버퍼(10개 정도였음. 소켓은 100여개 소켓이 붙었구요..)를 두고, 각 소켓에서
읽은 데이터가 규정된 패킷 프레임을 만족할 때까지 임시 버퍼에 넣어서 프레임 규정에 만족하면
그 다음 프로세서에 넘기는 형식으로 구성하였습니다.

다른 분들도 수신된 데이터로 규정된 프레임 데이터가 맞는 지에 대한 검증 로직을 거친 후
다음 로직으로 전달할 것으로 보여지네요..

인디 컴포넌트도 모르면서 썰이 길었습니다.
성공하시길..


:
: 고수님의 조언부탁드립니다.
: 감사합니다.

+ -

관련 글 리스트
62048 (인디사용)소켓통신시 에러처리 방법 문의드립니다. newhuni 1736 2010/07/29
62051     Re:(인디사용)소켓통신시 에러처리 방법 문의드립니다. 땅주인 2378 2010/07/29
62056         Re:Re:(인디사용)소켓통신시 에러처리 방법 문의드립니다. newhuni 2102 2010/07/30
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.