Q&A

  • Re: TServerSocket이랑 TClientSocket
이용일 께서 말씀하시기를...

> 서버에서 루프를 돌면서 디렉토리를 검색하여 그 문자열을 보내는 루틴이 있거든요. 당연히 클라이언트에는 받는 코드가 잇구요.

>

> 그런데 서버에서 보낸 문자열을 클라이언트에서는 빠르게 처리를 못해주더군요

> 즉 서버에서 루프를 돌면서 문자열을 몇개만 보내면 클라이언트에서 에러가 납니다.해결책은 잇더군요. 서버에서 문자열을 보낸다음에 delay를 시켜주는 방법.그런데 이것두 좋은 방법이 아닌거 같아서요(왜냐 너무 느리거든요)

> 해결책을 알려주세요.

> 끝까지 읽어주셔서 감사합니다.

>

> *DWinsock에서는 이것과 똑같은 코드를 짜서 실행해봤는데 잘만 되더군요

> 왜 그런거죠??버퍼가 커서 그런건가요??답변부탁드립니다.

>

>





이용일님 안녕하세요?

아래 질문하신 분께도 말씀드린건데

루프를 돌며 데이타를 전송하는 것은 안전한 데이타 전송을

보장할수 없습니다.

보내는 데이타의 크기를 말씀하지 않으셔서 정확한 답변을

드리진 못하지만, 시스템의 MTU크기보다 작게 잘라서

응답을 주고 받으며 전송을 하는 것이 안전합니다.

응답을 주고 받지 않고, 계속 전송만 한다면 시스템 버퍼에서

잘라서 보내어 주는 역할을 하게 되는데 끊임없이 루프를 돌며

데이타를 전송할시 그 데이타가 시스템버퍼에 누적되어

종적을 알수 없는 상황이 발생할지도 모릅니다.

DWinSock에서 똑같이 코드를 작성해서 성공하셨다구 하셨는데,

어떤 코드로 구성되었는지 궁금합니다.

공개 가능하시다면 소스를 올려주실수 있는지요?

그럼.. 항상 즐거운 프로그래밍 하시길 바랍니다.

2  COMMENTS
  • Profile
    구창민 1999.08.04 00:16
    이용일 께서 말씀하시기를...

    > 구창민 께서 말씀하시기를...

    > > 이용일 께서 말씀하시기를...

    > > > 서버에서 루프를 돌면서 디렉토리를 검색하여 그 문자열을 보내는 루틴이 있거든요. 당연히 클라이언트에는 받는 코드가 잇구요.

    > > >

    > > > 그런데 서버에서 보낸 문자열을 클라이언트에서는 빠르게 처리를 못해주더군요

    > > > 즉 서버에서 루프를 돌면서 문자열을 몇개만 보내면 클라이언트에서 에러가 납니다.해결책은 잇더군요. 서버에서 문자열을 보낸다음에 delay를 시켜주는 방법.그런데 이것두 좋은 방법이 아닌거 같아서요(왜냐 너무 느리거든요)

    > > > 해결책을 알려주세요.

    > > > 끝까지 읽어주셔서 감사합니다.

    > > >

    > > > *DWinsock에서는 이것과 똑같은 코드를 짜서 실행해봤는데 잘만 되더군요

    > > > 왜 그런거죠??버퍼가 커서 그런건가요??답변부탁드립니다.

    > > >

    > > >

    > >

    > >

    > > 이용일님 안녕하세요?

    > > 아래 질문하신 분께도 말씀드린건데

    > > 루프를 돌며 데이타를 전송하는 것은 안전한 데이타 전송을

    > > 보장할수 없습니다.

    > > 보내는 데이타의 크기를 말씀하지 않으셔서 정확한 답변을

    > > 드리진 못하지만, 시스템의 MTU크기보다 작게 잘라서

    > > 응답을 주고 받으며 전송을 하는 것이 안전합니다.

    > > 응답을 주고 받지 않고, 계속 전송만 한다면 시스템 버퍼에서

    > > 잘라서 보내어 주는 역할을 하게 되는데 끊임없이 루프를 돌며

    > > 데이타를 전송할시 그 데이타가 시스템버퍼에 누적되어

    > > 종적을 알수 없는 상황이 발생할지도 모릅니다.

    > > DWinSock에서 똑같이 코드를 작성해서 성공하셨다구 하셨는데,

    > > 어떤 코드로 구성되었는지 궁금합니다.

    > > 공개 가능하시다면 소스를 올려주실수 있는지요?

    > > 그럼.. 항상 즐거운 프로그래밍 하시길 바랍니다.

    >

    > 구창민님 답변 감사드리구요

    > 우선, 위에서 제가 말한것은 SendText로 디렉토리명과 파일명을 전송하는거였습니다. 이부분은 다시 답변부탁드릴께요.

    > 그리구 DWinsock 텍스트 전송하는건 LineReceived에서 받았어요.

    > 아주 빠르던데요..이렇게 하니까..이유가 뭐죠??^^;

    >



    이용일님 구창민입니다.

    SendText로 보냈든 SendBuf로 보냈든

    어찌되었건 바이트가 전송되게 됩니다.

    그것은 전송률에 따라 속도차가 나겠지요.

    그러나 위에서 말씀드린것 처럼 적은 바이트수라도

    받았다는 응답없이 계속 루프에서 문자열을 전송하는 것은

    안전을 보장할수 없게 되겠지요.

    특정 문자열을 전송하였다면 받은 측에서 반드시

    잘 받았다는 응답을 보내고 그때서 다시 다음 특정 문자열을

    전송하셔도 전혀 속도차를 느낄수 없을 것입니다.

    말씀드린 대로 다시 한번 작성해 보시고, 그래도

    속도가 나지 않는다면 소스를 공개가능하시면 그 부분이라도

    올려봐 주시겠습니까?

    제가 예제를 작성하려니 짧고 간단하게만은 되지 않을거 같아

    구두로만 말씀드렸습니다.

    시원한 답변이 아니어 죄송합니다.

    그럼..즐거운 프로그래밍 되시길~





  • Profile
    구창민 1999.08.04 01:33
    이용일 께서 말씀하시기를...

    > > 이용일님 구창민입니다.

    > > SendText로 보냈든 SendBuf로 보냈든

    > > 어찌되었건 바이트가 전송되게 됩니다.

    > > 그것은 전송률에 따라 속도차가 나겠지요.

    > > 그러나 위에서 말씀드린것 처럼 적은 바이트수라도

    > > 받았다는 응답없이 계속 루프에서 문자열을 전송하는 것은

    > > 안전을 보장할수 없게 되겠지요.

    > > 특정 문자열을 전송하였다면 받은 측에서 반드시

    > > 잘 받았다는 응답을 보내고 그때서 다시 다음 특정 문자열을

    > > 전송하셔도 전혀 속도차를 느낄수 없을 것입니다.

    > > 말씀드린 대로 다시 한번 작성해 보시고, 그래도

    > > 속도가 나지 않는다면 소스를 공개가능하시면 그 부분이라도

    > > 올려봐 주시겠습니까?

    > > 제가 예제를 작성하려니 짧고 간단하게만은 되지 않을거 같아

    > > 구두로만 말씀드렸습니다.

    > > 시원한 답변이 아니어 죄송합니다.

    > > 그럼..즐거운 프로그래밍 되시길~

    > >

    > >

    > 소스 여기 있어요.잘 봐주세요. 구창민님.^^

    > procedure TForm1.ClientSocketRead(Sender:TObject;Socket:TCustomWinSocket);

    > var

    > RTag,ReceiveText : String;

    > LengthByte,LengthKByte : Integer;

    > begin

    > ReceiveText := Socket.ReceiveText;

    > RTag := Copy(ReceiveText,1,4);

    > Delete(ReceiveText,1,4);

    > if RTag = 'DIR;' then

    > begin

    > with ListView1.Items.Add do begin

    > Caption := ReceiveText;

    > SubItems.Add('DIR');

    > end;

    > end;

    > if RTag = 'FIL;' then

    > begin

    > lengthByte := StrToInt(Copy(ReceiveText,Pos(':',ReceiveText)+1,Length(ReceiveText)-Pos(':',ReceiveText)));

    > lengthKByte := lengthByte div 1024;

    > Delete(ReceiveText,Pos(':',ReceiveText),Length(ReceiveText)- Pos':',ReceiveText)+1);

    > with ListView1.Items.Add do begin

    > Caption := ReceiveText;

    > if (UpperCase(Copy(ReceiveText,Pos('.',ReceiveText)+1,3)) = 'TXT') then

    > SubItems.Add(Copy(ReceiveText,Pos('.',ReceiveText)+1,3)+' file')

    > else SubItems.Add('');

    > if lengthKByte = 0 then

    > SubItems.Add(IntToStr(lengthByte )+' B')

    > else SubItems.Add(IntToStr(lengthKByte)+' KB');

    > end;

    > end;

    >

    > procedure TForm1.ServerSocketClientRead(Sender: TObject;

    > Socket: TCustomWinSocket);

    > var

    > ReceiveText,RTag : String;

    > R_FC : integer;

    > SearchRec : TSearchRec;

    > begin

    > ReceiveText := Socket.ReceiveText;

    > RTag := Copy(ReceiveText,1,Pos(';',ReceiveText));

    > Delete(ReceiveText,1,Pos(';',ReceiveText));

    > if RTag = 'DIR;' then

    > begin

    > Socket.SendText('SCH;START');

    > R_FC := FindFirst(ReceiveText+'*.*', faDirectory, SearchRec);

    > while R_FC = 0 do begin

    > if SearchRec.Attr = 16 then

    > Socket.SendText('DIR;'+SearchRec.Name);

    > R_FC := FindNext(SearchRec);

    > //제가 이부분에서 delay를 줬습니다.

    > end;

    >

    > R_FC := FindFirst(ReceiveText +'*.*', faArchive, SearchRec);

    > while R_FC = 0 do begin

    > if (SearchRec.Name <> '.') and (SearchRec.Name <> '..') then

    > Socket.SendText('FIL;'+SearchRec.Name+':'+IntToStr(SearchRec.Size));

    > R_FC := FindNext(SearchRec);

    > //이부분도 마찬가지..

    > end;

    > txtDIR.Caption := ReceiveText;

    > Socket.SendText('SCH;END');

    > FindClose(SearchRec);

    > end;

    > end;



    말씀드린 내용의 계속되는 반복인거 같아 죄송하지만,

    위의 소스에서도 While 문 속에 전송하는 부분이

    기술되어 있습니다.

    위와 같이 작성되어서는 안전한 전송을 보장할수

    없을거 같습니다.

    저도 실력이 별로이면서 이런말씀드려 죄송합니다.

    위의 소스를 While 문을 돌려 디렉토리 명을 긁어오는

    부분을 TStringList혹은 그외 문자열을 저장할수 있는

    객체를 사용하시거나 배열을 이용하시거나 하셔서

    먼저 문자열들을 담으신뒤에

    일정 크기로 잘라서 전송하시는 편이 안전하며 나을듯 합니다.



    지금 이 글이 꼬리가 넘 길어졌습니다.

    죄송하지만, 다른 의문점은 새로이 올려주시길 바랍니다.

    그럼.. 성공하시길 기원합니다~