Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TClientSocket и TServerSocket, как отследить передачу данных и заверш. 
V
    Опции темы
Marlin
Дата 10.3.2006, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 20.2.2006

Репутация: нет
Всего: 1



Как возможно отследить передачу данных, т.е. сколько данных передано и отследить окончание передачи этих же данных.
Это все нужно для отображения прогресса и закрытия соеденения.
Люди подскажите, а то у меня уже голова не соображает из за этих сокетов.

Данные отправляю одной строкой

Код

ClientSocket1.Socket.SendStream(TFileStream.Create(edit1.Text, fmOpenRead or fmShareDenyWrite));


Этот вопрос поднимался на форуме, но исходник где все это показано настолько намудрен, что я не могу разобраться.

Я предпологаю, что пакет данных который записывается нужно отслеживать в обработчике OnWrite и на этом мысль закнчивается
Подкинте если не трудно не навороченный пример с передачей файла от клиента к серверу и тображением прогресса на обоих точках, а по завершению передачи, клиент должен разрывать соеденение.

Это сообщение отредактировал(а) Marlin - 10.3.2006, 11:07
--------------------
Программист решает проблемы, о которых пользователь даже не задумывается,способами, о котороых он даже не подозревает.
PM MAIL   Вверх
Демо
Дата 10.3.2006, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 3
Всего: 50



Цитата(Marlin @ 10.3.2006, 11:06 Найти цитируемый пост)
Я предпологаю, что пакет данных который записывается нужно отслеживать в обработчике OnWrite


Нет, OnWrite срабатывает тогда, когда сокет
Код

готов к передаче.


Передавай частями SendBuf.


--------------------
    
PM MAIL ICQ Skype   Вверх
Marlin
Дата 10.3.2006, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 20.2.2006

Репутация: нет
Всего: 1



Я пробывал работать с инди, но он работает в блокирующем режиме, и вешает всю систему.

Прием файла я веду таким способом

Код


procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var
  iLen: Integer;
  Bfr: Pointer;
  begin
 
        iLen := Socket.ReceiveLength;
        GetMem(Bfr, iLen);

      try
        Socket.ReceiveBuf(Bfr^, iLen);
        FStream.Write(Bfr^, iLen);
      finally
        FreeMem(Bfr);
      end;

end;



Здесь прогресс отобразить возможно, передав сначала ему размер файла, а после прибавляя каждую порцию.
Но вот, что с клиентом делать.
Мой клиент время от времени должен конектиться и передавать файлы. Но почему-то первая передача проходит нормально, а на второй выдает ошибку. Я думаю это из за того, что я не могу отловить окончание передачи и нормально закрыть соеденения

--------------------
Программист решает проблемы, о которых пользователь даже не задумывается,способами, о котороых он даже не подозревает.
PM MAIL   Вверх
Marlin
Дата 10.3.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 20.2.2006

Репутация: нет
Всего: 1



Отправляю данные порциями.

А на сервере этот файл растет и растет пока принудительно не разорвешь соеденение.

код отправки
Код


procedure TForm1.N2Click(Sender: TObject);
var
f:TFileStream;
Buf:pointer;
i:integer;
CountRead:Longint;
SizeF:integer;
begin

  f:=TFileStream.Create(edit1.Text,fmOpenRead or fmShareDenyWrite);
  SizeF:=f.Size;
  ProgressBar1.Max:=SizeF;
  I:=0;
  ClientSocket1.Socket.SendText(IntToStr(SizeF));

  GetMem(Buf, SizeF);
  f.ReadBuffer(buf^,SizeF);

  While i<>SizeF do
    begin
      i:=i+1024;
      ClientSocket1.Socket.s
      ClientSocket1.Socket.SendBuf(buf^,1024);
      progressBar1.Position:=i;
      application.ProcessMessages;
    end;
  FreeMem(buf);
  ProgressBar1.Position:=0;
  f.Free;
  ClientSocket1.Active:=false;
end;



может что-то не так делаю

код приема

Код


procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
  var
  size:string;
  iLen: Integer;
  Bfr: Pointer;
  begin
  i:=i+1;
  If i=1 then
    begin
      size:=Socket.ReceiveText;
      ProgressBar1.Position:=0;
      ProgressBar1.Max:=StrToInt(size);
      FStream := TFileStream.Create('c:\temp\ttt.ddd', fmCreate or fmShareDenyWrite);
    end

  Else
      Begin

        iLen := Socket.ReceiveLength;
        ProgressBar1.position:=ProgressBar1.position+iLen;
        application.ProcessMessages;
        GetMem(Bfr, iLen);
      try
        Socket.ReceiveBuf(Bfr^, iLen);
        FStream.Write(Bfr^, iLen);
      finally
        FreeMem(Bfr);
      end;
  end;
end;


--------------------
Программист решает проблемы, о которых пользователь даже не задумывается,способами, о котороых он даже не подозревает.
PM MAIL   Вверх
Демо
Дата 10.3.2006, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 3
Всего: 50



Marlin,
Позже постараюсь пример сделать.


--------------------
    
PM MAIL ICQ Skype   Вверх
N1k
Дата 10.3.2006, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 4.1.2006

Репутация: 2
Всего: 2



Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, Gauges;

type
  TForm1 = class(TForm)
    ClientSocket1: TClientSocket;
    ServerSocket1: TServerSocket;
    Button1: TButton;
    Gauge1: TGauge;
    Gauge2: TGauge;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  M1,M2:TMemoryStream;
  Data:boolean=false;
implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  d:Int64;
begin
M1.LoadFromFile('c:\masm32.rar');
d:=M1.Size ;
ClientSocket1.Socket.SendBuf(d,sizeof(d));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
M1:=TMemoryStream.Create;
m2:=TMemoryStream.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
m1.Free;
m2.Free;
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  b: array[0..$FFF] of byte;
  d:Int64;
  rb:integer;
begin
if not Data then
  begin
  rb:=Socket.ReceiveLength;
  if rb >= sizeof(d) then
    begin
      Socket.ReceiveBuf(d,sizeof(d));
      Gauge1.MaxValue:=integer(d);
      Gauge1.Progress:=0;
      M2.Size:=d;
      Data:=true;
      Socket.SendText('Ok') ;
    end
  end  
else
  begin
  rb:=Socket.ReceiveBuf(b[0],sizeof(b));
  if rb > 0 then
  begin
    m2.Write(b[0],rb);
    Gauge1.Progress:=M2.Position;
    if M2.Size=M2.Position then
      begin
        Data:=false;
        m2.SaveToFile('c:\masm.rar');
      end
    else Socket.SendText('Ok') ;
  end;
  end;

end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  b: array[0..$FFF] of byte;
  rb:integer;
begin
if Socket.ReceiveText='Ok' then
  begin
  rb:=M1.Read(b[0],Sizeof(b));
  Socket.SendBuf(b[0],rb);
  Gauge2.MaxValue:=M1.Size;
  Gauge2.Progress:=M1.Position;
  end;
end;

end.

Но все это не больше чем пример.

PM MAIL   Вверх
Marlin
Дата 10.3.2006, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 20.2.2006

Репутация: нет
Всего: 1



спасибо сейчас пойду проверю
--------------------
Программист решает проблемы, о которых пользователь даже не задумывается,способами, о котороых он даже не подозревает.
PM MAIL   Вверх
Marlin
Дата 11.3.2006, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 20.2.2006

Репутация: нет
Всего: 1



Нет такой код не пойдет. Он файл заносит в оперативную память, а если файл 600 - 700 мб

А хочу зделать так:

Считать порцию файла и отправить, потомом опять считать и отправить, а на том конце тоже самое только наоборот.

Я так делал, только почему-то файл не дописывается.

Кому не сложно, я был бы рад помощи.
--------------------
Программист решает проблемы, о которых пользователь даже не задумывается,способами, о котороых он даже не подозревает.
PM MAIL   Вверх
Marlin
Дата 11.3.2006, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 20.2.2006

Репутация: нет
Всего: 1



Самое главное, чтобы файлы большого размера можно было бы передовать.

А TFileStream - файл подгружает в оперативку? как TMemoryStream
--------------------
Программист решает проблемы, о которых пользователь даже не задумывается,способами, о котороых он даже не подозревает.
PM MAIL   Вверх
N1k
Дата 11.3.2006, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 28
Регистрация: 4.1.2006

Репутация: 2
Всего: 2



Ну народ, я с вас варюсь...
Код

unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, Gauges;
type
  TForm1 = class(TForm)
    ClientSocket1: TClientSocket;
    ServerSocket1: TServerSocket;
    Button1: TButton;
    Gauge1: TGauge;
    Gauge2: TGauge;
    procedure Button1Click(Sender: TObject);
    procedure ServerSocket1ClientRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure FormCreate(Sender: TObject);
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);
  private
  public
  end;
var
  Form1: TForm1;
  FS1,FS2:Cardinal;
  M1,M2:cardinal;
  Data:boolean=false;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
M1:=CreateFile('c:\masm32.rar',GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
FS1:=GetFileSize(M1,0);
Gauge2.MaxValue:=FS1;
if ClientSocket1.Active and ServerSocket1.Active then
  ClientSocket1.Socket.SendBuf(FS1,sizeof(FS1));
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;    
  Socket: TCustomWinSocket);
var    
  b: array[0..$FFF] of byte;
  rb:integer;
  wb:dword;
begin
if not Data then
  begin
  rb:=Socket.ReceiveLength;
  if rb >= sizeof(FS2) then
    begin
      Socket.ReceiveBuf(FS2,sizeof(FS2));
      Gauge1.MaxValue:=integer(FS2);
      Gauge1.Progress:=0;
      Data:=true;
      if FS2 > 0 then
        begin
          M2:=CreateFile('c:\masm.rar',GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
          if M2 <> INVALID_HANDLE_VALUE then
            Socket.SendText('Ok') ;
        end
    end
  end    
else    
  begin    
  rb:=Socket.ReceiveBuf(b[0],sizeof(b));    
  if rb > 0 then
  begin
    WriteFile(M2,b[0],rb,wb,0);
    Gauge1.Progress:=Gauge1.Progress + rb;
    if Gauge1.Progress=Gauge1.MaxValue then
      begin
        Data:=false;
        CloseHandle(M2)
      end
    else Socket.SendText('Ok') ;
  end;    
  end;    
end;
procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);    
var    
  b: array[0..$FFF] of byte;    
  rb:DWORD;

begin
if Socket.ReceiveText='Ok' then
  begin
  ReadFile(m1,b[0],Sizeof(b),rb,0);
  Socket.SendBuf(b[0],rb);
  Gauge2.Progress:=Gauge2.Progress+rb;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
ServerSocket1.Active:=true;
Sleep(3000);
ClientSocket1.Active:=true;
end;

procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Button1.Enabled:=true;
end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Button1.Enabled:=false
end;

end.

PM MAIL   Вверх
Marlin
Дата 11.3.2006, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 20.2.2006

Репутация: нет
Всего: 1



Спасибо!!

Похоже это то, что нужно.
--------------------
Программист решает проблемы, о которых пользователь даже не задумывается,способами, о котороых он даже не подозревает.
PM MAIL   Вверх
Marlin
Дата 13.3.2006, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 170
Регистрация: 20.2.2006

Репутация: нет
Всего: 1



Я немного подправил код. код который выше.
А то большие файлы не докачиваются до конца.


SERVER

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, Gauges;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    ServerSocket1: TServerSocket;
    Gauge1: TGauge;
    procedure ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientDisconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  fileName:string = '';
  FN:string;
  reseveTxt:boolean=false;
  data:boolean=false;
  FS2:Cardinal;
  M2:cardinal;

implementation

{$R *.dfm}

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memo1.Lines.Add('conect has done');
end;

procedure TForm1.ServerSocket1ClientDisconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memo1.Lines.Add('conect has broken');
end;

procedure TForm1.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  b: array[0..1024] of char;
  rb:integer;
  wb:dword;
  i:integer;
begin

if (not Data) and (not reseveTxt) then
  begin
    fileName:=Socket.ReceiveText;
    fn:='c:\temp\'+fileName;
    reseveTxt:=true;
    Socket.SendText('size');
  end

else

if (not Data) and (reseveTxt=true) then
  begin
  rb:=Socket.ReceiveLength;
  if rb >= sizeof(FS2) then
    begin
      Socket.ReceiveBuf(FS2,sizeof(FS2));
      Gauge1.MaxValue:=integer(FS2);
      Gauge1.Progress:=0;
      Data:=true;
      if FS2 > 0 then
        begin
          M2:=CreateFile(PChar(fn),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
          if M2 <> INVALID_HANDLE_VALUE then
            Socket.SendText('Ok') ;
        end
    end
  end

else

  begin    
  rb:=Socket.ReceiveBuf(b,sizeof(b));
  if rb > 0 then
  begin
    WriteFile(M2,b,rb,wb,0);
    Gauge1.Progress:=Gauge1.Progress + rb;
    if Gauge1.Progress=Gauge1.MaxValue then
      begin
        Data:=false;
        reseveTxt:=false;
        CloseHandle(M2);
        Gauge1.Progress:=0;
        Socket.SendText('end');
      end
    else Socket.SendText('Ok');
  end;    
  end;    
end;

end.


CLIENT
Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, StdCtrls, Gauges;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    ClientSocket1: TClientSocket;
    Edit1: TEdit;
    Label1: TLabel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    OpenDialog1: TOpenDialog;
    Gauge2: TGauge;
    Edit2: TEdit;
    procedure ClientSocket1Connect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ClientSocket1Disconnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure Button3Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  FS1:Cardinal;
  M1:cardinal;

implementation

{$R *.dfm}

procedure TForm1.ClientSocket1Connect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memo1.Lines.Add('conect has done');
end;

procedure TForm1.ClientSocket1Disconnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
memo1.Lines.Add('conect has broken');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
ClientSocket1.Host:=edit2.Text;
ClientSocket1.Active:=true;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if Opendialog1.Execute then
edit1.Text:=OpenDialog1.FileName;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
M1:=CreateFile(PChar(edit1.text),GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
FS1:=GetFileSize(M1,0);
Gauge2.MaxValue:=FS1;
if ClientSocket1.Active then
  begin
    ClientSocket1.Socket.SendText('myFile.dty');
  end;
end;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var    
  b: array[0..1024] of char;
  rb:DWORD;
  t:string;
begin
t:=Socket.ReceiveText;
if t='size' then
   Socket.SendBuf(FS1,sizeof(FS1))
else

if t='Ok' then
  begin
    ReadFile(m1,b,Sizeof(b),rb,0);
    Socket.SendBuf(b,rb);
    Gauge2.Progress:=Gauge2.Progress+rb;
  end

Else

if t='end' then
  begin
    CloseHandle(m1);
    Socket.Close;
    Gauge2.Progress:=0;
  end;

end;
end.


Это сообщение отредактировал(а) Marlin - 13.3.2006, 11:30
--------------------
Программист решает проблемы, о которых пользователь даже не задумывается,способами, о котороых он даже не подозревает.
PM MAIL   Вверх
ukk
Дата 28.3.2006, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 9
Регистрация: 20.12.2005
Где: Минск

Репутация: нет
Всего: нет



А не мог бы кто нить исходником выполнить, тоже самое что и чуть выше написанно, только без прогресса (тоесть без Gauge) и побольше коммента ? Буду очень благодарен!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0902 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.