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
[36937] 감사합니다. 그런데.... Packet에 Error라 발생할때는 고려가 되어있지 않네요
장성호 [] 1474 읽음    2004-08-23 18:04
감사합니다
NonBlocking   ThreadBlocking 에 대해서는 많은 도움이 된것 같습니다.

그런데 님에 code에도 전송되는 Data에 전송중에 Data가 변형되거나  깨어지거나 하는 경우는 고려가 되어있지 않네요

1024Byte씩 전송하고 있는데 수신측에 Data가 송신측의 Data와 100% 항상 똑같다고 할수는 없잖아요?

제 경우   파일전송부분에 CheckSum을 추가했습니다.
------------------------------------------------------------------------------

#define MAX_BUFFER_SIZE 1024

void __fastcall TFileSendThread::Execute()
{
    TFileStream* pStream;
    char         pBuff[MAX_BUFFER_SIZE];
    int          nCopySize;
    char chkSum;
    Main->Pb_Tx->Position = 0;
    String fname=ExtractFileName(TxFileName);
    int fsize,txsize=0;
    try
    {
        pStream = new TFileStream(TxFileName, fmOpenRead);
        fsize= pStream->Size;
        Main->Pb_Tx->Max = pStream->Size;
        Main->ClientSocket->Socket->SendText(fname + "," + IntToStr(pStream->Size)+"@");
        while (true)
        {
            nCopySize = pStream->Read(pBuff, MAX_BUFFER_SIZE);
            txsize+=nCopySize;
            chkSum=pBuff[0];
            for(int i=1;i<nCopySize;i++)   chkSum=chkSum^pBuff[i];  //체크섬을 만든다.

            pBuff[nCopySize] =chkSum;
            pBuff[nCopySize+1] = '\0';

            if (nCopySize != 0)
                 Main->ClientSocket->Socket->SendBuf(pBuff, MAX_BUFFER_SIZE+1); //1024+1 Byte씩 전송
             else
                break;
        }

        Application->ProcessMessages();

        if(Main->ErrPacket->Count>0)
        {
            int packet=StrToInt(Main->ErrPacket->Strings[0]);
            pStream->Seek(packet*1024,soFromBeginning );
            nCopySize = pStream->Read(pBuff, MAX_BUFFER_SIZE);
            chkSum=pBuff[0];
            for(int i=1;i<nCopySize;i++)
                 chkSum=chkSum^pBuff[i];

            pBuff[nCopySize] =chkSum;
            pBuff[nCopySize+1] =packet/256;
            pBuff[nCopySize+2] =packet%256;

            pBuff[nCopySize+3] = '\0';
            Main->ClientSocket->Socket->SendBuf(pBuff, nCopySize+3);  //1024+3Byte씩 전송
            Main->ErrPacket->Delete(0);
        }
    }
    __finally
    {
        delete pStream;
    }

    Main->ClientSocket->Socket->SendText("");
    Main->Memo_Tx->Lines->Add("파일송신 끝");
    Main->Memo_Tx->Lines->Add("파일Size:"+IntToStr(fsize));
    Main->Memo_Tx->Lines->Add("파일TxSize:"+IntToStr(txsize));
}
--------------------------------------------------------------------------
---------------------수신측에서는 -----------------------------------------

전체 수신Data에서 맨마지막 Data까지 XOR를 한후에 그것과 맨마지막 Byte와 비교합니다.
여기서 똑같지 않으며 다시 전송해달라고 요청하지요
송신측에서는 재전송요청 Message를 위에 code에서는 ErrPacket이라는 TStringList에 담아둡니다.

-------------------------------------------------------------------------
Error는 종종발생하더라구요
송수신측 모두 Local이거나  File크기가 작을때는 적게 나타나는데
File 크기가 커질수록 자주 나타나더라구요



이점한 님이 쓰신 글 :
: 사람들은 TServerSocket의  쓰레드블럭킹의 강력함을 잘 모르더군요.
: 우리나라에서는 소스 조차 찾기 힘들고 외국 소스 몇개 참조 했는데
: 제대로 정리해서 강좌식으로 올리려고 작년부터 마음 먹었었는데 시간이 안되
: 못올리는군요. 아예 소스를 첨부 할테니 내용 참조 하세요.
: TServerSocket의 쓰레드 블럭킹 예제입니다.
: 소스 내의 디렉토리 몇개는 바꾸셔야 할것입니다. 다운 로드 폴더를 임의로 "C:\temp"로 했거든요.
: 바로 쓰실려면 아마 "C:\temp"라는 디렉토리 만들어 두셔야 할 것입니다.
: 현재 피시방 관리프로그램이랑 휴대폰 결제 프로그램에 응용해서 사용 되고 있는 루틴입니다.
: Project1은 쓰레드블럭킹을 이용하는 서버구요.  Project2는 클라이언트입니다.
: 쓰레드에서 스트리밍 전송이 되기 때문에 여러 사용자 동시 다운로드도 가능합니다.
: 보통 NonBlocking으로 하면 다운로드 중에 다른 사용자가 다운로드 시도하면 첫번째넘은 일시정지
: 되는데 쓰레드 블럭킹은 전혀 그런것 없습니다.
:
: 일단 소스 첨부 해드릴테니깐 잘 참조 하세요. 생각외로 소스는 간단하답니다.
:
: 앞으로 시간이 되면 스레드블럭킹에 대한 자세한 강좌를 약속드리며....
:
: 참 구글 같은데서 "ClientSocket->"이거나 "TMyServerThread" 이거로 검색 하시면 제꺼와
: 유사한 소스는 몇개 찾으실겁니다. 주로 일본이나 미국 볼랜드포럼 개발자 사이트가 많이 나오더군요.
:
:
: 장성호 님이 쓰신 글 :
: : 안녕하세요
: : 소켓으로 파일 전송하고자 합니다.
: : (참고할수 있는 자료나 책같은것이라도 소개 좀 부탁드립니다.)
: :
: : C++Builder의 TServerSocket과 TClientSocket을 쓰고있습니다.
: :
: : 맨처음 File Name과 File Size를 전송합니다.
: :
: : 그다음 File을 일정한 크기(1024BYte)씩 짤라서  전송합니다.
: : 그런데 가끔 전송중간에 Error가 나는수 있더라구요
: : 그것을 확인하기 위해 Data맨뒤에 CheckSum을 1Byte추가했습니다.
: : CheckSum은 모든Data를 XOR했구요
: :
: : Data를 수신한후 CheckSum에 문제가 있으면
: : 해당Packet을 다시 전송해달라고 송신측에 메세지를 보냅니다.
: :
: : 송신측에서는 재전송요청을 받으면
: : 해당Packet의 Data+CheckSum+Packet번호 를 송신합니다.
: : Packet번호는 2Byte입니다.
: :
: :
: : 즉 일단 file을 모두 전송한후에
: : 저쪽에서 error가 있다는 부분만 다시 전송해주는 구조입니다.
: :
: : [한번에 전송되는 data구조 1,2,3]
: : 1 - FileName+FileSize              ==> 맨처음에 file에 대한 정보를 전송한다.
: : 2 - Data+CheckSum                 ==> 다음. 일정크기+1Byte =1025Byte 씩 data를 전송합니다.... File끝까지
: : .
: : .
: : 3 - Data+CheckSum+Packet번호  ==>마지막으로 일정크기+1Byte+2Byte=1027Byte  error packet을 전송합니다.
: :
: : 전송종료는 data를 모두 전송후에 일정시간(2초)이상 error패킷에 대해 재전송 요청이 없으면
: : 전송을 마무리하구요
: :
: : 수신측에서는 Data를 완벽하게 수신했거나  에러packet이 있을경우 송신측에서 일정시간 전송해주시 않으면
: : 그냥 수신실패한것으로 마무리 합니다.
: :
: :
: : 문제점과 의문나는점은?
: :
: : 1) 재전송요청한 packet에서 계속반복해서 Error가 나는경우가 있구요
: : 2) 처음 file전송시(2번)에는 data에 대한 packet번호를 수신측에서 차례대로 수신한다고 생각하고
: :     함께 전송하지 않습니다.--> 그래도 되는지...?
: : 3) 송신측에서 전송중에 재전송요청을 받았을때.. 그 부분부터 다시보내는것이 좋을런지...?
: : 4) 보통 메신져(MSN이나 NateOn 같은데)에서는 어떻게 하는지?
: : 5) CheckSum 만드는 더좋은 방법이 있으면 소개좀 부탁드립니다.
: : 6) 마지막을 ZModem처음 전송되는 Packet의 크기를 가변적으로 하려면  어떻게 해야하죠?
: :     에러가 없으면 점점 전송되는 packet의 크기가 커지는것으로 알고잇는데....  (너무 막연한 질문인가?)
: :
: : 목표
: : 가능한한  최대한 빠르게 파일이 전송 되어야합니다.
: : 그럴러면 전송되는 data에 Header가 적어야겠죠(반드시 그렇지는 않겠지만)
: : 그리고 당연히 수신file에 1Byte라도 error는 없어야겠구요?
: : 마지막으로 수신측에서도 Acknowledge같은것도 최대한 적게 보내야 합니다.
: : XMODEM이나 YMODEM같은경우는 한번수신할때만다 Acknowledge를 보내는것으로 알고있습니다.(맞나?)
: :
: : 참고로 이 파일전송 부분은 직접구현해야합니다.
: : FTP나 다른 컴포넌트를 이용할수 없습니다.

+ -

관련 글 리스트
36935 소켓으로 파일전송시하는데... 좋은 알고리즘 좀 가르쳐 주세요 장성호 2997 2004/08/23
36940     빌더 5로 컨버젼 해주시면 안될까요.-인디와 다른점은.. 하안인 1253 2004/08/23
36942         Re: 컨버젼 .. 간단하니까 직접하셔도.. 될듯.. 장성호 1217 2004/08/23
36941         Indy 컴포넌트와 다른점은 무엇인가요 하안인 1319 2004/08/23
36944             Re:Indy 컴포넌트와 다른점은 무엇인가요 이점한 1605 2004/08/23
36945                 감사합니다. 하안인 880 2004/08/24
36937         감사합니다. 그런데.... Packet에 Error라 발생할때는 고려가 되어있지 않네요 장성호 1474 2004/08/23
36943             Re:^^; 이점한 1853 2004/08/23
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.