Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Передача файла


Автор: Exai1e 29.10.2007, 10:55
Здрасти, возник вот такой вопрос:

Где можно почитать статейку или глянуть исходник вот такого плана приложения:
Клиент передает на сервер файл, Сервер принимает и отправляет его всем подключенным клиентам кроме того кто отсылал этот фаил. Просто на форуме есть примеры передачи файлов на основе сокетов, но там от Сервера к Клиенту, а мне бы прмиерчик всего этого да только наоборот

интерисует прмиер \ статья с использованием TServerSocket, TClientSocket

Спасибо

Автор: Alexeis 29.10.2007, 11:30
Exai1e, 
Цитата(Exai1e @  29.10.2007,  10:55 Найти цитируемый пост)
интерисует прмиер \ статья с использованием TServerSocket, TClientSocket

  Насколько я знаю эти компоненты признаны устаревшими, вместо них следует использовать TIdTCPServer, TIdTCPClient, TIdUDPServer, TIdUDPClient.

Автор: Exai1e 30.10.2007, 22:54
Вот такое дело:

клиент:
Код

unit uMainClient;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Buttons, ComCtrls, ToolWin, Menus, ScktComp, Sockets;

type
  TfrmMain = class(TForm)
    ClientSocket1: TClientSocket;
    MainMenu1: TMainMenu;
    sdsd1: TMenuItem;
    ToolBar1: TToolBar;
    StatusBar1: TStatusBar;
    btnConnect: TSpeedButton;
    btnDisconnect: TSpeedButton;
    btnSendFile: TSpeedButton;
    edtAddress: TEdit;
    OpenDialog1: TOpenDialog;
    Edit1: TEdit;
    procedure ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
    procedure btnSendFileClick(Sender: TObject);
    procedure btnConnectClick(Sender: TObject);
    procedure btnDisconnectClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    fs : TFileStream;
    Reciving : boolean;
    DataSize : Integer;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.btnConnectClick(Sender: TObject);
begin
  ClientSocket1.Address := edtAddress.Text;
  ClientSocket1.Active := true;
  StatusBar1.Panels.Items[0].Text := 'Connecting true';
end;

procedure TfrmMain.btnDisconnectClick(Sender: TObject);
begin
  ClientSocket1.Active := false;
  StatusBar1.Panels.Items[0].Text := 'Connecting false';
end;

procedure TfrmMain.btnSendFileClick(Sender: TObject);
var
  SendFile : TFileStream;
begin
  if OpenDialog1.Execute then Edit1.Text := OpenDialog1.FileName;

  ClientSocket1.Socket.SendText('FileGoServer');
  SendFile := TFileStream.Create(OpenDialog1.FileName, fmOpenRead);
  try
    SendFile.Position := 0;
    ClientSocket1.Socket.SendText('Size:' + IntToStr(SendFile.Size) + #0);
    ClientSocket1.Socket.SendStream(SendFile);
  finally
  end;
end;


procedure TfrmMain.ClientSocket1Read(Sender: TObject; Socket: TCustomWinSocket);
var
  s, sl: string;
begin
  s:= Socket.ReceiveText;

  if Reciving then
    begin
      fs.Write(s[1], length(s));
        if fs.Size=DataSize then
          begin
            fs.Free;
            Reciving:=false;
            Application.MessageBox('Поздравляю, Client принял фаил', 'Внимание!!!');
          end;
      exit;
  end;

  if copy(s, 1, 5)='Size:' then
    begin
      sl:=copy(s, 6, Pos(#0, s)-6);
      DataSize:=StrToInt(sl);
      Delete(s, 1, Pos(#0, s));
      Reciving:=true;
      fs:=TFileStream.Create('output.jpeg',fmCreate);
      fs.Write(s[1], length(s));
      exit;
    end;
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  ClientSocket1.Active := false;
  StatusBar1.Panels.Items[0].Text := 'Connecting false';
end;

end.


сервер:
Код

unit uMainServer;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, Buttons, ToolWin, ComCtrls, Menus;

type
  TfrmMain = class(TForm)
    MainMenu1: TMainMenu;
    s1: TMenuItem;
    StatusBar1: TStatusBar;
    ToolBar1: TToolBar;
    btnStartServer: TSpeedButton;
    btnStopServer: TSpeedButton;
    ServerSocket1: TServerSocket;
    OpenDialog1: TOpenDialog;
    procedure ServerSocket1ClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure btnStopServerClick(Sender: TObject);
    procedure btnStartServerClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    fs : TFileStream;
    Reciving : boolean;
    DataSize : Integer;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

{$R *.dfm}

procedure TfrmMain.btnStartServerClick(Sender: TObject);
begin
  ServerSocket1.Active := true;
  StatusBar1.Panels.Items[0].Text := 'Server active true';
end;

procedure TfrmMain.btnStopServerClick(Sender: TObject);
begin
  ServerSocket1.Active := false;
  StatusBar1.Panels.Items[0].Text := 'Server active false';
end;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
  ServerSocket1.Active := false;
  StatusBar1.Panels.Items[0].Text := 'Server active false';
end;

procedure TfrmMain.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket);
var
  s, sl: string;
  FileSend : TFileStream;
begin
  s:= Socket.ReceiveText;

  if Reciving then
    begin
      fs.Write(s[1], length(s));
        if fs.Size=DataSize then
          begin
            fs.Free;
            Reciving:=false;
            Application.MessageBox('Поздравляю, Сервер принял фаил', 'Внимание!!!');
          end;
      exit;
  end;

  if copy(s, 1, 5)='Size:' then
    begin
      sl:=copy(s, 6, Pos(#0, s)-6);
      DataSize:=StrToInt(sl);
      Delete(s, 1, Pos(#0, s));
      Reciving:=true;
      fs:=TFileStream.Create('output.jpeg',fmCreate);
      fs.Write(s[1], length(s));
      exit;
    end;

    //------------------------------
  OpenDialog1.Execute;
  ServerSocket1.Socket.SendText('FileGoClient');
  FileSend := TFileStream.Create(OpenDialog1.FileName, fmOpenRead);
  try
    FileSend.Position := 0;
    ServerSocket1.Socket.SendText('Size:' + IntToStr(FileSend.Size) + #0);
    ServerSocket1.Socket.SendStream(FileSend);
  finally
  end;
   //------------------------------
end;

end.


С клиента на сервер фаил передаеться, а вот с сервера на клиент не хочет, т.е. сначало фаил кидаеться на сервер а с сервера уже отсылаеться клиенту
Выскакивает вот такая ошибка:
http://img86.imageshack.us/img86/1219/20615104vw6.jpg

Нашел расшифровку ошибки
"Error # 10057 Socket is not connected - Была предпринята попытка передать или принять данные через неподключенный сокет."

ток немогу понять, как это через не подключенный сокет, коннект же между программами установлен :-/

Автор: AugMaster 14.12.2007, 02:59
ServerSocket1.Socket.SendText('FileGoClient');
и все остальные попытки посылать данные через связку  ServerSocket1.Socket окончатся неудачей.
Просто используй сокет,который тебе передается в procedure TfrmMain.ServerSocket1ClientRead(Sender: TObject;
  Socket: TCustomWinSocket); - это и есть сокет клиента,который подключен. А ты стучался неизвестно куда "ServerSocket1.Socket." этой записью  .То есть твоя передача должна выглядеть так

Код

OpenDialog1.Execute;
Socket.SendText('FileGoClient');//  ServerSocket1.Socket.SendText('FileGoClient');
  FileSend := TFileStream.Create(OpenDialog1.FileName, fmOpenRead);
  try
    FileSend.Position := 0;
Socket.SendText('Size:' + IntToStr(FileSend.Size) + #0);//    ServerSocket1.Socket.SendText('Size:' + IntToStr(FileSend.Size) + #0);
Socket.SendStream(FileSend);//    ServerSocket1.Socket.SendStream(FileSend);
  finally
  end;


по-идее должно работать. Хотя может возникнуть ситуация, когда в буфере нет места. Это уже посложнее задачка. Придется обрабатывать событие OnWrite

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)