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
[43596] 님 감사합니다.. ^^ 해결되었네요..
pili [] 987 읽음    2006-02-08 09:22
감사합니다. 님 말씀처럼 테스트를 해보니 2번 출력이 되네요.. ReceiveLength()를 사용해 실제값이 0인경우 바루

리턴을 시키니.. 잘 되네요... ^^ 다시한번 감사 드립니다.. 그럼 즐거운 하루 보내세요....^^


ㅇ 님이 쓰신 글 :
: pili 님이 쓰신 글 :
: : 먼저 읽어주셔서 감사합니다.
: :
: : 다름이 아니라 TClientSocket과 TServerSocket을 이용해 구조체를 주고 받습니다.
: :
: : 문제는 아래와 같이 작성해서 돌려보면 결과값이 2번씩 출력되네요..ㅜ.ㅜ..
: :
: : 문제될꼐 없는 것 같은데.. 혹시 뭐가 잘 못된게 있나해서 이렇게 글을 남김니다. 그럼 즐거운 하루 보내세요.
: :
: : 코드는 다음과 같습니다.
: :
: : ---공 통---
: : #define     sDeleteMessageLen       sizeof(DELETEMESSAGE)
: : typedef struct sDeleteMessage
: : {
: :     unsigned char szFlag;
: :     char szItemGuid[32];
: :     char szuName[32];
: : }DELETEMESSAGE, *PDELETEMESSAGE;
: :
: : ---클라이언트---
: : 전송부분
: :         DELETEMESSAGE* pDeleteMessage = new DELETEMESSAGE;
: :         pDeleteMessage ->szFlag = MSGID_DELETEMESSAGE;
: :         strcpy(pDeleteMessage ->szuName, "Test");
: :         strcpy(pDeleteMessage ->szItemGuid, "TestGuid");
: :
: :         csock->Socket->SendBuf((char*)pDeleteMessage , sDeleteMessageLen );
: :
: : -- 서버부분 --
: : 서버부분 헤더에 구조체에 대해 공용체로 선언해 놓았습니다.
: : typedef union
: : {
: :     unsigned char   uType;
: :     DELETEMESSAGE   stDeleteMessage;
: :     SEARCHITEMREQ   stSearchItemReq;
: : } RCVCLIENTDATA;
: :
: : 받는 부분--
: : RCVCLIENTDATA pRcvClientData;
: : Socket->ReceiveBuf((char*)&pRcvClientData, 1);  <-- 공용체의 uType을 확인 한 후 switch를 수행합니다.
: :
: : switch(pRcvClientData.uType)
: :         {
: :         case MSGID_DELETEMESSAGE:
: :             Socket->ReceiveBuf(((char*)&pRcvClientData) + 1, sDeleteMessageLen );
: :             Memo1->Lines->Add(pRcvClientData.stSearchItemPon.szmFlag);
: :             Memo1->Lines->Add(pRcvClientData.stSearchItemPon.szmFlag);
: :             Memo1->Lines->Add(pRcvClientData.stSearchItemPon.szmFlag);
: :             break;
: :         case ....
: :         case ....
: :             break;
: :         default:
: :             break;
: :         }
:
: 클라이어트가 한 번의 SendBuf 호출로 보낸 데이터에 대해 서버에서는 OnClientRead 이벤트 핸들러가 여러번 호출될 수 있습니다. 예를 들면, 클라이언트가 보낸 데이터를 앞에서부터 셋으로 나누어 세번 호출할 수 있습니다.
:
: 한편, 함수 내부의 비정적변수들은 스택에 생성이 되고 return 시에는 해당 스택영역을 반납하게 되며 다른 함수 호출로 그 값이 변하게 되는게 보통인데 동일한 함수를 동일한 매개변수로 연속하여 호출하면 이전에 스택에 생성된 변수들의 값이 그대로 살아 있게 됩니다.
:
: 지금 상황은 위의 두 가지가 동시에(복합적으로) 발생한 것입니다.
:
: 이 문제를 해결하려면, 아래와 같이 ReceiveLength()로 조사하여 실제 읽어들일 데이터가 없으면 그냥 return하면 됩니다.
:
: 한편, 정말 두 번 이상 호출되고 사용했던 스택영역을 그대로 다시 사용하여 값이 살아 있게 되는 것인지 테스트해보려면 위 검사를 하지 말고 함수 끝부분에서 strcpy(pRcvClientData.stDeleteMessage.szuName, "정말 그렇네");를 해보세요.
: 그러면, 두번째 이후 호출될 때 클라이언트가 보낸 내용과 달리 "정말 그렇네"가 출력되는 것을 확인할 수 있을 것입니다.

:
: 그리고, ReceiveBuf의 반환값을 확인하세요.
: 만약, 받고자 하는 양보다 적다면 다 받을 때까지 반복해서 받아야 합니다.
:
:  Memo1->Lines->Add(String("Read: ")+Socket->RemoteAddress+":"+Socket->RemotePort);
:  if(Socket->ReceiveLength()==0) return;
:
:  RCVCLIENTDATA pRcvClientData;
:  Socket->ReceiveBuf((char*)&pRcvClientData, 1);  <-- 공용체의 uType을 확인 한 후 switch를 수행합니다.
:  switch(pRcvClientData.uType)
:  {
:   case MSGID_DELETEMESSAGE:
:      Socket->ReceiveBuf(((char*)&pRcvClientData) + 1, sDeleteMessageLen );
:      Memo1->Lines->Add(pRcvClientData.stDeleteMessage.szFlag);
:      Memo1->Lines->Add(pRcvClientData.stDeleteMessage.szItemGuid);
:      Memo1->Lines->Add(pRcvClientData.stDeleteMessage.szuName);
:      break;
:   default:
:      break;
:  }

+ -

관련 글 리스트
43592 TServer Socket에서 ReceiveBuf()관련입니다. pili 1255 2006/02/07
43595     Re:TServer Socket에서 ReceiveBuf()관련입니다. 2114 2006/02/08
43596         님 감사합니다.. ^^ 해결되었네요.. pili 987 2006/02/08
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.