indy의 IdTCPServer, IdTCPClient로 파일 전송을 구현하려고 합니다.
서버쪽 :
procedure TForm1.tcpServerExecute(AThread: TIdPeerThread);
var
Cmd : String;
FStream : TFileStream;
begin
Cmd := AThread.Connection.ReadLn('',100);
if Cmd = 'SEND' then
begin
if Application.MessageBox('파일전송을 허락하겠습니까','file',MB_ICONQUESTION or MB_YESNO) = IDYES Then
begin
AThread.Connection.WriteLn('OK');
if FileExists('C:a.asf') then
DeleteFile('C:a.asf');
Listbox1.Items.Add('수신중');
FStream := TFileStream.Create('파일명',fmCreate);
AThread.Connection.ReadStream(FStream,-1,True);
Listbox1.Items.Add('수신완료');
FStream.Free;
end
else AThread.Connection.WriteLn('NO');
AThread.Connection.Disconnect;
end;
end;
클라이언트 :
procedure TForm1.Button1Click(Sender: TObject);
begin
IdTCPClient1.Writeln('SEND')
end;
//타이머에서 서버쪽을 응답에 따라 전송합니다.
procedure TForm1.Timer1Timer(Sender: TObject);
var
FStream : TFileStream;
Cmd : String;
begin
IF Not IdTCPClient1.Connected then
Exit;
Cmd := IdTCPClient1.ReadLn('',100);
if Cmd <> '' then
begin
if Cmd = 'OK' then
begin
FStream := TFileStream.Create('파일명',fmOpenRead);
IdTCPClient1.WriteStream(FStream);
FStream.Free;
IdTCPClient1.Disconnect;
end
else if Trim(Cmd) = 'NO' then
begin
IdTCPClient1.Disconnect;
end;
end;
end;
위처럼 코딩하여 실행하면 전송은 잘 됩니다. 여기에다 진행현황을 프로그레스
바로 표현하려고 하는데 방법을 잘 모르겠읍니다.
소스를 보면 스트림으로 파일을 송수신 할때 자동으로 잘러서 보내던데
서버, 클라이언트 양쪽에서 프로그래스바로 지행사항을 표현할수 없을까요?
고수님들 제~발 답변좀 남겨 주세요!!!
이미 알고계시겠지만 이런 방법으로 파일을 전송하면 나누어 보내는 것 보다 더 느립니다. 왜냐구요? 그건 잘 모르겠구요 해보니까 더 느리더라구요
파일을 나누어 보내려면 얼마의 크기로 나눌것인지 정한 후에 받는 쪽에 먼저 파일크기를 알려주면(WriteBuffer를 이용하여 파일이름,파일크기등을 보내는 것이 좋겠습니다.) 받는 쪽에서는 파일크기와 미리정한 블럭크기를 가지고 몇개의 데이터블럭이 전송되어 올것인지 계산할 수 있겠죠?(적당히 5K미만이 좋겠습니다.) 그다음 파일을 받을 준비가 되었다는 코드를 보내줍니다.
파일을 받을 준비가 되었다는 코드를 받고 나면 이제 파일을 보내면 됩니다. 파일스트림을 직접 네트워크로 전송하지 마시고 아까정한 블럭크기로 나누어서 읽은 후- FStream.Read(버퍼,읽을크기)
읽은 버퍼를 idTCPClient1.WriteBuffer함수로 보냅니다.
버퍼를 보낸 후에는 받는 쪽에서 버퍼를 '받았다는 코드'를 보내주고 보내는 쪽에서 '받았다는 코드'를 받으면 모든 데이터 블럭이 보내질 때 까지 위의 명령을 반복하여 다음 데이터블럭을 보냅니다.
받는쪽에서는 데이터블럭을 받을 때마다 카운트를 증가하고 앞에서 계산한 총 블럭수를 가지고 프로그래스바를 그릴 수 있겠지요 (예를들어 총 1000개의 블럭중 300번째 블럭을 받았다면 30%를 가르키는 프로그래스바를 그릴 수 있지요) 마찬가지로 보내는 쪽도 블럭을 보낼 때 마다 프로그래스바를 그릴 수 있구요
받드시 받았다는 코드를 받은 후에 다음 블럭을 보내도록 하세요 TCP/IP는 패킷방식의 전송을 하니까 하나 데이터블럭을 구성하는 TCP/IP 패킷은 순서가 뒤바뀌지 않겠지만 각 블럭은 TCP/IP에서 말하는 패킷이 아니라 우리가 임의로 잘라서 보내는 거니까 도착하는 순서를 보장할 수 없죠 그렇지 않고 한꺼번에 보내면 첫번째 블럭과 두번째 블럭을 순차적으로 보내더라도 상황에 따라 두번째 블럭이 먼저 도착할 수 있지 않겠어요?
철 wrote:
> indy의 IdTCPServer, IdTCPClient로 파일 전송을 구현하려고 합니다.
>
> 서버쪽 :
> procedure TForm1.tcpServerExecute(AThread: TIdPeerThread);
> var
> Cmd : String;
> FStream : TFileStream;
> begin
> Cmd := AThread.Connection.ReadLn('',100);
> if Cmd = 'SEND' then
> begin
> if Application.MessageBox('파일전송을 허락하겠습니까','file',MB_ICONQUESTION or MB_YESNO) = IDYES Then
> begin
> AThread.Connection.WriteLn('OK');
> if FileExists('C:a.asf') then
> DeleteFile('C:a.asf');
> Listbox1.Items.Add('수신중');
> FStream := TFileStream.Create('파일명',fmCreate);
> AThread.Connection.ReadStream(FStream,-1,True);
> Listbox1.Items.Add('수신완료');
> FStream.Free;
> end
> else AThread.Connection.WriteLn('NO');
> AThread.Connection.Disconnect;
> end;
> end;
>
> 클라이언트 :
> procedure TForm1.Button1Click(Sender: TObject);
> begin
> IdTCPClient1.Writeln('SEND')
> end;
>
> //타이머에서 서버쪽을 응답에 따라 전송합니다.
> procedure TForm1.Timer1Timer(Sender: TObject);
> var
> FStream : TFileStream;
> Cmd : String;
> begin
> IF Not IdTCPClient1.Connected then
> Exit;
> Cmd := IdTCPClient1.ReadLn('',100);
> if Cmd <> '' then
> begin
> if Cmd = 'OK' then
> begin
> FStream := TFileStream.Create('파일명',fmOpenRead);
> IdTCPClient1.WriteStream(FStream);
> FStream.Free;
> IdTCPClient1.Disconnect;
> end
> else if Trim(Cmd) = 'NO' then
> begin
> IdTCPClient1.Disconnect;
> end;
> end;
> end;
>
> 위처럼 코딩하여 실행하면 전송은 잘 됩니다. 여기에다 진행현황을 프로그레스
> 바로 표현하려고 하는데 방법을 잘 모르겠읍니다.
> 소스를 보면 스트림으로 파일을 송수신 할때 자동으로 잘러서 보내던데
> 서버, 클라이언트 양쪽에서 프로그래스바로 지행사항을 표현할수 없을까요?
> 고수님들 제~발 답변좀 남겨 주세요!!!
>