Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 01.01.2012, 23:50   #1
Alexandr555
Форумчанин
 
Регистрация: 23.03.2011
Сообщений: 310
По умолчанию передача файла частями TcpServer TcpClient

возникла проблема что файл например 600кб передается не весь
решил попробовать поделить на части по 50кб
клиент передает
Код:
var
  stream: TMemoryStream;
  i: integer;
  p: Pointer;
Код:
    stream := TMemoryStream.Create;
    stream.LoadFromFile(Edit2.Text);
 if stream.Size<51200 then
     begin
      if TcpClient1.Receiveln = 'ok' then
       TcpClient1.SendBuf(stream.Memory^, stream.Size);
      if TcpClient1.Receiveln = 'ok' then ShowMessage('Êíèãà îòïðàâëåíà!');
     end
    else
     begin
      for i:=0 to (stream.Size div 51200)  do
       begin
         if TcpClient1.Receiveln = 'ok' then
          begin
           CopyMemory(p, stream.Memory,51200);
           TcpClient1.SendBuf(p, 51200);
          end;
       end;
       if TcpClient1.Receiveln = 'ok' then ShowMessage('Êíèãà îòïðàâëåíà!');
     end;
сервер принмает
Код:
if sz<51200 then
       begin
        stream.SetSize(sz);
        ClientSocket.ReceiveBuf(stream.Memory^, sz);
        stream.SaveToFile(extractfilepath(paramstr(0))+'lib\'+put+name);
        ClientSocket.Sendln('ok');
       end
      else
       begin
        for i:=0 to (stream.Size div 51200)  do
         begin
          ClientSocket.ReceiveBuf(stream.Memory^, 51200);
          ClientSocket.Sendln('ok');
         end;
        stream.SaveToFile(extractfilepath(paramstr(0))+'lib\'+put+name);
        ClientSocket.Sendln('ok');
       end;
это не весь код, перед этим сервер получил размер файла он в sz

вопрос как копировать кусочки по 50кб и отправлять
а то сдается что CopyMemory(p, stream.Memory,51200); не правильно...
Alexandr555 вне форума Ответить с цитированием
Старый 02.01.2012, 00:47   #2
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

1. на что ссылается указатель p?
2. даже если будет правильно ссылаться, то CopyMemory(p, stream.Memory,51200) всегда будет читать от начала
3.
Код:
var b: array [1..51200] of Byte;
..
stream.Position:=0;
for i:=0 to (stream.Size div 51200)  do begin
  stream.ReadBuffer(b,51200);
  ...
end;
и передавайте указатель на b в SendBuf
имейте ввиду, что длина последнего блока может быть меньше 51200 или вообще нулевая
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.01.2012, 01:24   #3
Alexandr555
Форумчанин
 
Регистрация: 23.03.2011
Сообщений: 310
По умолчанию

Спасибо!
переделал клиент
Код:
if stream.Size<51200 then
     begin
      if TcpClient1.Receiveln = 'ok' then
       TcpClient1.SendBuf(stream.Memory^, stream.Size);
      if TcpClient1.Receiveln = 'ok' then ShowMessage('Êíèãà îòïðàâëåíà!');
     end
    else
     begin
      stream.Position:=0;
      for i:=0 to (stream.Size div 51200)  do
       begin
         if TcpClient1.Receiveln = 'ok' then
          begin
           if (i= stream.Size div 51200) then
            stream.ReadBuffer(b,stream.Size mod 51200)
           else stream.ReadBuffer(b,51200);

           if (i= stream.Size div 51200) then
            TcpClient1.SendBuf(b,stream.Size mod 51200)
           else TcpClient1.SendBuf(b, 51200);
          end;
       end;
       if TcpClient1.Receiveln = 'ok' then ShowMessage('Êíèãà îòïðàâëåíà!');
     end;
сервер
Код:
if sz<51200 then
       begin
        stream.SetSize(sz);
        ClientSocket.ReceiveBuf(stream.Memory^, sz);
        stream.SaveToFile(extractfilepath(paramstr(0))+'lib\'+put+name);
        ClientSocket.Sendln('ok');
       end
      else
       begin
        for i:=0 to (stream.Size div 51200)  do
         begin
          if (i= stream.Size div 51200) then ClientSocket.ReceiveBuf(stream.Memory^, stream.Size mod 51200)
          else
           begin
            ClientSocket.ReceiveBuf(stream.Memory^, 51200);
            ClientSocket.Sendln('ok');
           end;

         end;
        stream.SaveToFile(extractfilepath(paramstr(0))+'lib\'+put+name);
         ClientSocket.Sendln('ok');
       end;
про то что последний блок меньше 50кб забыл совсем)
но я что то не понял как мне указатель то передать? пока в таком варианте только ошибку выдавало 10054(что сервер закрыл соединение)
Alexandr555 вне форума Ответить с цитированием
Старый 02.01.2012, 12:06   #4
Alexandr555
Форумчанин
 
Регистрация: 23.03.2011
Сообщений: 310
По умолчанию

вот что не так?

Код:
  b: array [1..51200] of Byte;
  p : ^Byte;
Код:
      stream.Position:=0;
      for i:=0 to (stream.Size div 51200)  do
       begin
         if TcpClient1.Receiveln = 'ok' then
          begin
           if (i= stream.Size div 51200) then
            stream.ReadBuffer(b,stream.Size mod 51200)
           else stream.ReadBuffer(b,51200);
           p:=addr(b);
           if (i= stream.Size div 51200) then
            TcpClient1.SendBuf(p,stream.Size mod 51200)
           else TcpClient1.SendBuf(p, 51200);
          end;
       end;
Alexandr555 вне форума Ответить с цитированием
Старый 02.01.2012, 12:15   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

TcpClient1.SendBuf(b,... - правильно будет
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 02.01.2012, 12:56   #6
Alexandr555
Форумчанин
 
Регистрация: 23.03.2011
Сообщений: 310
По умолчанию

Код:
      stream.Position:=0;
      for i:=0 to (stream.Size div 51200)  do
       begin
         if TcpClient1.Receiveln = 'ok' then
          begin
           if (i= stream.Size div 51200) then
            stream.ReadBuffer(b,stream.Size mod 51200)
           else stream.ReadBuffer(b,51200);
           p:=addr(b);
           if (i= stream.Size div 51200) then
            TcpClient1.SendBuf(b,stream.Size mod 51200)
           else TcpClient1.SendBuf(b, 51200);
          end;
       end;
ну и так собственно тоже не работает
может он частями не правильно принимает?
Код:
        for i:=0 to (stream.Size div 51200)  do
         begin
          if (i= stream.Size div 51200) then ClientSocket.ReceiveBuf(stream.Memory^, stream.Size mod 51200)
          else
           begin
            ClientSocket.ReceiveBuf(stream.Memory^, 51200);
            ClientSocket.Sendln('ok');
           end;

         end;
Alexandr555 вне форума Ответить с цитированием
Старый 02.01.2012, 15:16   #7
Alexandr555
Форумчанин
 
Регистрация: 23.03.2011
Сообщений: 310
По умолчанию

клиент
Код:
     begin
      stream.Position:=0;
      for i:=0 to (stream.Size div 51200)  do
       begin
         if TcpClient1.Receiveln = 'ok' then
          begin
           if (i= stream.Size div 51200) then
            stream.ReadBuffer(b,stream.Size mod 51200)
           else stream.ReadBuffer(b,51200);
           if (i= stream.Size div 51200) then
            TcpClient1.SendBuf(b,stream.Size mod 51200)
           else TcpClient1.SendBuf(b, 51200);
          end;
       end;
       if TcpClient1.Receiveln = 'ok' then ShowMessage('Книга отправленна!');
     end;
сервер
Код:
       stream.SetSize(sz);
      if sz<51200 then
       begin
        ClientSocket.ReceiveBuf(stream.Memory^, sz);
        stream.SaveToFile(extractfilepath(paramstr(0))+'lib\'+put+name);
        ClientSocket.Sendln('ok');
       end
      else
       begin
        for i:=0 to (stream.Size div 51200)  do
         begin
          if (i= stream.Size div 51200) then ClientSocket.ReceiveBuf(stream.Memory^, stream.Size mod 51200)
          else
           begin
            ClientSocket.ReceiveBuf(stream.Memory^, 51200);
            ClientSocket.Sendln('ok');
           end;

         end;
        stream.SaveToFile(extractfilepath(paramstr(0))+'lib\'+put+name);
         ClientSocket.Sendln('ok');
       end;
в общем вот говорит что книга отправленна, но в файле ровно 51200 байт
Alexandr555 вне форума Ответить с цитированием
Старый 02.01.2012, 18:04   #8
Alexandr555
Форумчанин
 
Регистрация: 23.03.2011
Сообщений: 310
По умолчанию

добил

прием у сервера
Код:
  stream: TMemoryStream;
  Twostream: TMemoryStream;


      if sz<51200 then
       begin
        ClientSocket.ReceiveBuf(stream.Memory^, sz);
        stream.SaveToFile(extractfilepath(paramstr(0))+'lib\'+put+name);
        ClientSocket.Sendln('ok');
       end
      else
       begin
        stream.Position:=0;
        for i:=0 to (sz div 51200)  do
         begin
          if (i= sz div 51200) then
           begin
            ClientSocket.ReceiveBuf(Twostream.Memory^, sz mod 51200);
            stream.WriteBuffer(Twostream.Memory^,sz mod 51200);
           end
          else
           begin
            ClientSocket.ReceiveBuf(Twostream.Memory^, 51200);
            stream.WriteBuffer(Twostream.Memory^,51200);
            ClientSocket.Sendln('ok');
           end;

         end;
        stream.SaveToFile(extractfilepath(paramstr(0))+'lib\'+put+name);
         ClientSocket.Sendln('ok');
       end;
      Twostream.Free;
      stream.Free;
     end;
клиент
Код:
      stream.Position:=0;
      for i:=0 to (stream.Size div 51200)  do
       begin
         if TcpClient1.Receiveln = 'ok' then
          begin
           if (i= stream.Size div 51200) then
            stream.ReadBuffer(b,stream.Size mod 51200)
           else stream.ReadBuffer(b,51200);
           if (i= stream.Size div 51200) then
            TcpClient1.SendBuf(b,stream.Size mod 51200)
           else TcpClient1.SendBuf(b, 51200);
          end;
       end;
       if TcpClient1.Receiveln = 'ok' then ShowMessage('Êíèãà îòïðàâëåíà!');
     end;
иногда вот случается ошибка 10054
а потом повторно нормально или через несколько ошибок таких нормально =(

Последний раз редактировалось Alexandr555; 02.01.2012 в 18:07.
Alexandr555 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
отправка файла через TcpServer/TcpClient Alexandr555 Работа с сетью в Delphi 15 20.12.2011 22:20
TCPServer, TCPClient seobot Общие вопросы Delphi 2 03.05.2010 23:56
Чат на TCPClient\TCPServer, передача файлов! AquaKlaster Работа с сетью в Delphi 3 18.05.2009 21:03
Передача файлов(exe) при помощи TCPServer и TCPClient Air Работа с сетью в Delphi 6 26.12.2008 23:26
TcpClient и TcpServer DOLBY Работа с сетью в Delphi 5 17.12.2007 10:43