Задать вопрос
Mik92
@Mik92

ServerSocket/ClientSocket передача файла — почему криво передает?

Доброго времени суток, пытаюсь передать файл с помощью ServerSocket на ClientSocket. Передает нормально и размер обрабатывает верно но переданный файл совсем не правильный и испорченный. Пожалуйста, скажите что я делаю не так при передаче или при приеме файла.
Сервер (отправляет):
private
    ms: TMemoryStream;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  ServerSocket1.Port:= 2000;
  ServerSocket1.Open;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
var
  ms: TMemoryStream;
  Size: Integer;
begin
  if Socket.ReceiveText = 'send' then
  begin
    ms:= TMemoryStream.Create;
    try
      ms.LoadFromFile('C:\msdia80.dll');
      ms.Position:= 0;
      Socket.SendText(IntToStr(ms.Size));
      Socket.SendStream(ms);
    except
      ms.Free;
    end;
  end;
end;


Клиент (принимает):
private
    Reciving: boolean;
    DataSize: integer;
    Data: TMemoryStream;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  ClientSocket1.Open;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject; Socket: TCustomWinSocket);
begin
  Socket.SendText('send');
end;

procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
  s, sl: string;
begin
  s:= Socket.ReceiveText;
  if not Reciving then
  begin
    SetLength(sl, StrLen(PChar(s))+1);
    StrLCopy(@sl[1], PChar(s), Length(sl)-1);
    DataSize:= StrToInt(sl);
    Data:= TMemoryStream.Create;
    Delete(s, 1, Length(sl));
    Reciving:= true;
  end;
  try
    Data.Write(s[1], length(s));
    if Data.Size = DataSize then
    begin
      Data.Position:= 0;
      Data.SaveToFile('1.dll');
      Data.Free;
      Reciving:= false;
      Socket.Close;
      ShowMessage('ок');
    end;
  except
    Data.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientSocket1.Address:= '127.0.0.1';
  ClientSocket1.Port:= 2000;
end;
  • Вопрос задан
  • 1734 просмотра
Подписаться 1 Оценить Комментировать
Решения вопроса 1
@akileev
Java / Scala developer
У вас при передаче длины файла в переменной sl может оказаться часть данных файла. Из-за этого будет ошибка конвертации строки в число. Надо клиентом подключиться, запросить файл, далее сервер передает длину файла. Клиент ее получает, потом запрашивает сам файл. Сервер начинает его передавать.

procedure TForm1.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
  s, sl: AnsiString;
begin
  s := Socket.ReceiveText;
  if not Reciving then
  begin
    SetLength(sl, StrLen(PAnsiChar(s)) + 1);
    StrLCopy(@sl[1], PAnsiChar(s), Length(sl) - 1);
    DataSize := StrToInt(sl);
    Data := TMemoryStream.Create;
    Delete(s, 1, Length(sl));
    Reciving := True;
    Socket.SendText('sendfile');
    Exit;
  end;
  try
    Data.Write(s[1], Length(s));
    if Data.Size = DataSize then
    begin
      Data.Position := 0;
      Data.SaveToFile('1.dll');
      Data.Free;
      Reciving := false;
      Socket.Close;
      ShowMessage('ок');
    end;
  except
    Data.Free;
  end;
end;


procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  ms: TMemoryStream;
  Size: Integer;
  Command: AnsiString;
begin
  Command := Socket.ReceiveText;
  if Trim(Command) = 'send' then
  begin
    ms := TMemoryStream.Create;
    try
      ms.LoadFromFile
        ('C:\ttxsql_project\Technotronics_Project\Run\libeay32.dll');
      ms.Position := 0;
      Socket.SendText(IntToStr(ms.Size));
    except
      ms.Free;
    end;
  end
  else if Trim(Command) = 'sendfile' then
  begin
    ms := TMemoryStream.Create;
    try
      ms.LoadFromFile
        ('C:\ttxsql_project\Technotronics_Project\Run\libeay32.dll');
      ms.Position := 0;
      Socket.SendStream(ms);
    except
      ms.Free;
    end;
  end;
end;
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы