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
[44291] Re:파일 수신시 패킷 오류 관련(스레드 서버 소켓)- 좀더 자세한 원인 발견...
Mani [agaree] 1175 읽음    2006-03-27 19:32
음...원인이 BufferSize가 '0'이고 나서 다시 읽어 오면 패킷 형태가 달라 지네요....-_-

BufferSize = pStream->Read(tmpBuffer, (sizeof(sSendHeader ) - NowLength)) ;

'0'을 리턴하는데 실제로는 읽어 왔다????

이렇게 생각을 해야 할까요???-_-??

제가 잘못을 한 건지 아니면 원래 문제 인지 모르겠네요...
제가 잘못 한거 였으면 좋겠습니다....

만약 C++ 빌더 문제라면...-_- 더 복잡해 지겠죠.....ㅎㅎ

mani 님이 쓰신 글 :
: 클라이언트가 파일을 보내면 서버가 받아서 저장하는 프로그램을 만들고 있습니다.
: 서로 주고 받는 것은 구조체 형태로 받고 있고요
: 구조는
: #pragma pack(1)
: typedef struct  {
:     unsigned long  Length ; //Packet 총 길이에서 Packet Header 길이 제외
:     unsigned long  File_TotLength ;//요청한 파일의 total length
:     unsigned long  SentLength ; //현재까지 수신한 파일의 length
:
: } SendHeader ;
:
: #pragma pack(1)
: typedef struct  {
:     char FileStream[4096] ; //MP3 Stream Data
:
: } SendFile ;
:
: 이렇게 헤더와 바디를 따로 구분해서 보내고 받습니다.
:
: 근데 수신을 받다 보면 패킷이 이상하게 들어 옵니다.
: 헤더가 안들어 오고 바로 바디가 들어 오네요....
:
: 보내는 로직
:        SendHeader  sSendHeader  ;
: SendFile sSendFile ;
:         filestream = new TFileStream(Filename ,fmOpenRead) ;
:
:         filestream->Seek( 0 , soFromBeginning) ;
:         FileLength = filestream->Size ;
:         Cnt = (FileLength / 4096) + 1 ;
:
:         for (int Loop1 = 0 ; Loop1 < Cnt ; Loop1 ++)
:         {
:             if (SendGo == false)
:             {
:                 ClientSocket1->Active = false ;
:                 break ;
:             }
:             memset(&sSendHeader , 0 , sizeof(sSendHeader)) ;
:
:             if (FileLength - (Loop1 * 4096) > 4096)
:                 SendLength = 4096 ;
:             else
:                 SendLength = FileLength - (Loop1 * 4096) ;
:
:             filestream->Read(&sSendFile.FileStream ,SendLength ) ;
:             sSendMP3Header.Length = SendLength ;
:             sSendMP3Header.File_TotLength = FileLength ;
:             sSendMP3Header.SentLength = ((Loop1 * 4096) +SendLength)  ;
:             ClientSocket1->Socket->SendBuf(&sSendHeader , sizeof(sSendHeader)) ;
:             ClientSocket1->Socket->SendBuf(&sSendFile , sizeof(sSendFile)) ;
:
:             if (Loop1 != Cnt-1)
:                 filestream->Seek(0 , soFromCurrent) ;
:             Sleep(1) ;
:         }
:     }
:
: 클라이언트에서 이렇게 보냅니다.
:
: 서버에서는 파일 길이를 다 받을 때까지 루프를 돌면서 헤더와 바디를 구분합니다.
: 클라이언트가 3개 정도 붙으면 문제가 안되는데 4개 이상붙으면 헤더값이 이상한게 들어 오는 넘들이 있습니다.
: 아래 소스 보시면 아시겠지만
:
:                 if (RcvLength <= 0 || RcvLength > 4096)
:                 {
:                     SocketWrite_Log("[패킷 오류]" , 1) ;       //  RcvLength 가 4096 이상이 될 수가 없슴          
:                     RecieveEnd = true ;
:                     break ;
:                 }
:
: RcvLength 는 4096이 넘을 수 없습니다.
: 근데 패킷을 받다보면 터무니 없는 값(억단위가 넘는 값이죠..-_-)이 들어 옵니다.
: 그래서 확인한 결과 바디에 와야 할 내용이 헤더로 들어 오고 있다는 것을 알게 되었습니다.
:
: 근데 지금까지 받은 바디 사이즈 그리고 전체 패킷 사이즈를 기록해 봤는데
: 패킷오류가 나는 시점에서도 사이즈는 정상 입니다.
: 예를 들면 바디사이즈는 4096으로 나누면 값이 딱 떨어 집니다.
: 전체 패킷 값도 4108 로 나누면 나머지가 12가 남습니다
: 여기서 12는 헤더 정보를 받아 온 후이기 때문에 12가 남는것은 당연한 것이구요...
:
: 혹시 제가 발견하지 못한 오류나 아니면 생각지도 못했더 로직상의 오류가 있는지 모르겠네요...
:
: 며칠째 이거 가지고 씨름하다가 이렇게 글을 올립니다.
:
: 고수님들의 도움 부탁 드립니다.
:
: 서버에서는 아래와 같이 받아 옵니다.
:
:        String sFilename ;
:       sFilename = "c:\a.txt" ;
:
:         if (!FileExists(sFilename))
:             sFileHandle = FileCreate(sFilename) ;
:
:         RecieveEnd = false ;
:         SocketWrite_Log("[수신시작" , 1) ;
:         RcvYn = "N" ;
:
:        SendFile sSendFile ;
:        SendHeader sSendHeader ;
:
:     int fFileSize = 0 ;
:     int NowLength ;
:     int TotalRcvPackLen = 0 ;
:     char *tmpBuffer      ;
:     tmpBuffer =  new char[sizeof(sSendHeader )+1] ;
:     char tmpBuffer3[sizeof(sSendHeader )] ;
:     char tmpBuffer4[sizeof(sSendFile)] ;
:     char *tmpBuffer2 ;
:     tmpBuffer2 = new char[sizeof(sSendFile)+1] ;
:
:     while (!RecieveEnd)
:     {
:         try
:         {
:             memset(tmpBuffer3, 0x0, 12);
:             memset(&sSendHeader , 0x0 , 12) ;
:             memset(tmpBuffer , 0x0 , 13) ;
:             NowLength = 0 ;
:             LoopCnt = 1 ;
:             try
:             {
:                 while ( NowLength < sizeof(sSendHeader ))
:                 {
:                     try
:                     {
:                         BufferSize = pStream->Read(tmpBuffer, (sizeof(sSendHeader ) - NowLength)) ;
:                     }
:                     catch(Exception &E)
:                     {
:                         ClientSocket->Close();
:                         RecieveEnd = true ;
:                         break ;
:                     }
:
:                     if( BufferSize == 0)   // 입력된 값이 없으면 종료
:                     {
:                         if (LoopCnt == 1000)
:                         {
:                             ClientSocket->Close();
:                             RecieveEnd = true ;
:                             break ;
:                         }
:                         LoopCnt+= 1 ;
:
:                         try
:                         {
:                             WaitForSingleObject((HANDLE)Handle , 10) ; //약간의 Sleep을 주기 위해 사용
:                         }
:                         catch(...)
:                         {
:                             ::Sleep(10) ;
:                         }
:                         continue ;
:                     } else
:                     {
:
:                         memcpy((void *)&tmpBuffer3[NowLength] , (void *)&tmpBuffer[0] , BufferSize) ;
:                         NowLength = NowLength  + BufferSize ;
:                         if ( NowLength == 12)
:                             break ;
:                         try
:                         {
:                             WaitForSingleObject((HANDLE)Handle , 2) ;
:                         }
:                         catch(...)
:                         {}
:                     }
:
:                 }
:                 if (RecieveEnd)
:                 {
:                     break ;
:                 }
:                 TotalRcvPackLen = TotalRcvPackLen + 12 ;
:                 Move(tmpBuffer3 , &sSendHeader , 12) ;
:
:                 SaveFileLenth = sSendHeader.SentLength ;
:                 RcvLength = sSendHeader.Length ;
:                 TotalLength = sSendHeader.File_TotLength ;
:
:                 if (RcvLength <= 0 || RcvLength > 4096)
:                 {
:                     SocketWrite_Log("[패킷 오류]" , 1) ;       //  RcvLength 가 4096 이상이 될 수가 없슴          
:                     RecieveEnd = true ;
:                     break ;
:                 }
:             }
:             catch(Exception &E)
:             {
:                 RecieveEnd = true ;
:                 break ;
:             }
:
:             NowLength = 0 ;
:             LoopCnt = 1 ;
:             memset(&sSendFile , 0x0 , sizeof(sSendFile)) ;
:             memset(tmpBuffer4 , 0x0 , sizeof(sSendFile)) ;
:             memset(tmpBuffer2, 0x0, sizeof(sSendFile)+1);
:             try
:             {
:                 while ( NowLength < RcvLength)
:                 {
:                     try
:                     {
:                         BufferSize = pStream->Read(tmpBuffer2, RcvLength - NowLength) ;
:                     }
:                     catch(Exception &E)
:                     {
:                         ClientSocket->Close();
:                         RecieveEnd = true ;
:                         break ;                       
:                     }
:                     if ( BufferSize == 0)
:                     {
:                         if (LoopCnt == 1000)
:                         {
:                             ClientSocket->Close();
:                             RecieveEnd = true ;
:                             break ;
:                         }
:                         LoopCnt+= 1 ;
:
:                         try
:                         {
:                             WaitForSingleObject((HANDLE)Handle , 10) ;
:                         }
:                         catch(...)
:                         {
:                             ::Sleep(10) ;
:                         }
:                         continue ;
:
:                     }
:                     else
:                     {
:
:                         memcpy((void *)&tmpBuffer4[NowLength] , (void *)&tmpBuffer2[0] , BufferSize) ;
:                         fFileSize = fFileSize + BufferSize ;
:                         NowLength = NowLength + BufferSize ;
:                         if ( NowLength ==  RcvLength)
:                             break ;
:                         //::Sleep(10) ;
:                         try
:                         {
:                             WaitForSingleObject((HANDLE)Handle , 1) ;
:                         }
:                         catch(...)
:                         {}
:                     }
:                 }
:             }
:             catch(Exception &E)
:             {
:                 RecieveEnd = true ;
:                 break ; 
:             }
:             TotalRcvPackLen = TotalRcvPackLen + NowLength ;
:             Move(tmpBuffer4 , &sSendFile , NowLength) ;
:             try
:             {
:                 FileSeek(sFileHandle,0,2);
:                 FileWrite(sFileHandle, sSendFile.FileStream , RcvLength ) ;
:             }
:             catch(Exception &E)
:             {
:                 RecieveEnd = true ;
:             }
:            
:             if (FileLength == fFileSize )
:             {
:                 RecieveEnd = true ;
:             }
:             try
:             {
:                 WaitForSingleObject((HANDLE)Handle , 10) ;
:             }
:             catch(...)
:             {
:                 ::Sleep(10) ;
:             }           
:
:         }
:         catch ( Exception &except )
:         {
:             ClientSocket->Close();
:             ErrorCode = "4" ;
:             RecieveEnd = true ;
:         }
:     }
:     FileClose(sFileHandle);

+ -

관련 글 리스트
44289 파일 수신시 패킷 오류 관련(스레드 서버 소켓) mani 1319 2006/03/27
44299     [자답]파일 수신시 패킷 오류 관련(스레드 서버 소켓)... 그러나 또 다른 문제...-_- Mani 1498 2006/03/28
44291     Re:파일 수신시 패킷 오류 관련(스레드 서버 소켓)- 좀더 자세한 원인 발견... Mani 1175 2006/03/27
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.