При отправке ответа FILE_DOWNLOAD
сервер вызывает IOHandler.Write(String)
вместо IOHandler.WriteLn()
для отправки строк FILE_DOWNLOAD
и имени файла. Строки не заканчиваются на CRLF
, но клиент использует ReadLn()
для чтения этих строк. Таким образом, он никогда не достигает точки, где он пытается создать файл и прочитать его.
При этом я бы предложил несколько альтернативный дизайн для вашего протокола и кода.
Вам не нужно отправлять имена файлов в их собственных строках. Они должны быть в той же строке, что и команды, которым они принадлежат.
TIdIOHandler.Write(TStream)
и TIdIOHandler.ReadString()
могут обрабатывать отправку / чтение размера потока для вас. Вам не нужно отправлять / читать размер вручную, и, конечно, не в виде строки.
Попробуйте вместо этого:
Клиент
var
XLSFolder: string;
...
MyIdTCPClient.IOHandler.WriteLn('SEND_FILE 1.XLS');
...
if MyIdTCPClient.IOHandler.InputBufferIsEmpty then
begin
MyIdTCPClient.IOHandler.CheckForDataOnSource(10);
if MyIdTCPClient.IOHandler.InputBufferIsEmpty then Exit;
end;
S := MyIdTCPClient.IOHandler.ReadLn();
Cmd := Fetch(S);
if Cmd = 'FILE_DOWNLOAD' then
begin
AStream := TFileStream.Create(XLSFolder + S, fmCreate);
try
MyIdTCPClient.IOHandler.LargeStream := True;
MyIdTCPClient.IOHandler.ReadStream(AStream, -1, False);
finally
AStream.Free;
end;
end;
...
initialization
XLSFolder := ExtractFilePath(Paramstr(0)) + 'XLS\';
Сервер
procedure TServerMainForm.IdTCPServerExecute(AContext: TIdContext);
var
AStream : TFileStream;
cmd, params, filename: String;
begin
params := AContext.Connection.IOHandler.ReadLn();
cmd := Fetch(params);
if cmd = 'SEND_FILE' then
begin
filename := ExtractFilename(params);
try
AStream := TFileStream.Create('<some path>\' + filename, fmOpenRead or fmShareDenyWrite);
except
AContext.Connection.IOHandler.WriteLn('FILE_DOWNLOAD_ERR ' + filename);
Exit;
end;
try
AContext.Connection.IOHandler.WriteLn('FILE_DOWNLOAD ' + filename);
AContext.Connection.IOHandler.LargeStream := True;
AContext.Connection.IOHandler.Write(AStream, 0, True);
finally
AStream.Free;
end;
end;
end;