client-server i tablica rekordów?

0

witam mam otóż ciekawą <ort>wkestię </ort>do rozwiązania
zastanawiam się czy da się za pomocą programu client pobrać dane będące w tablicy w programie server, a także wysłać z client dane do tablicy na server? jeśli tak, to czy koś ma pomysła jak to zrobić? :]

0

Jaki w tym problem? Klient np wysyla jakies zadanie o ktorys tam element tablicy, serwer to odczytuje i wysyla ten element. Najlepiej, zeby przed jakim kolwiek transferem wysylany byl jakiegos rodzaju header informujacy o tym, co mamy zamiar wyslac i ile to ma zajmowac.

0

a czy ta metoda jest szybsza niż używanie plików? tj czy szybciej client pobierze dane z tablicy, czy szybciej pobierze dane z jakiegoś pliku na serwerze?

0

A ?<ort>z kad</ort>? w ogole przyszly ci pliki na mysl? Wiadomo, ze odczyt tablicy z ram jest szybsze niz pliku (choc, jesli jest to bardzo male i odczytane jeden raz to roznica bedzie marginalna). Z reszta nie do konca kapuje o co chodzi w tym rozwiazaniu z plikami :| .

0

otóż mamy na serwerze pliki powiedzmy z 1000 i w nich dane
każdy plik zawiera max 1kb
to samo mamy w 1000-elementowej tablicy danych w programie servera
(array[1..1000]of rekorddanych)
z serwerem lączy się jednocześnie 1000 osób
co szybciej będzie, gdyby te 1000 osób otworzyło odpowiedni dla siebie plik (w zależności od ID jakie posiadają) i pobrali dane i zapisali w tablicy programu client, czy też gdyby odwołali się do tablicy danych na serverze i dane z niego zapisali również w tablicy danych clienta?

ale ja motam :]
wolverine, a może jakiś przykłądzik prosty "zapodasz"? :]

0

Ogolnie tablica w pamieci bedzie zawsze szybsza, ale zwrocic tez nalezy uwage na to, ze jesli ten ID uzytkownika bedzie w jego rekordzie to bedzie trzeba przeszukac ta tablice, przy odczycie pliku zajmie sie tym system plikow i przypuszczam, ze zrobi to szybciej (choc moge sie mylic). W sumie, taka rzecz bardzo latwo sprawdzic, ustaw tablice na powiedzmy 10k elementow i tyle samo plikow, w tablicy element szukany na koncu i powrownaj. Co do przykladu, to nie wiem za bardzo co to ma byc za przyklad.

0

Wolverine, chciałbym abyś mi pomógł przekształcić ponizsze kody tak aby prócz samego transferu plików można było przesyłać wartości do tablicy, tj. z programu client z tablicacli przesyłamy jej wartości do tablicaserv na server i odwrotnie, poniżej wrzuciłem kody źródłowe
dzięki z góry za pomoc

<font color="red">client</span>
unit Client;

interface

uses
{$IFDEF Linux}
QGraphics, QControls, QForms, QDialogs, QStdCtrls,
{$ELSE}
windows, messages, graphics, controls, forms, dialogs, stdctrls,
{$ENDIF}
SysUtils, Classes, IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient,
IdTrivialFTP;

type
<font color="green">tablicacli=array[1..100]of integer; //tu mają być dane</span>
TfrmMain = class(TForm)
edtRemoteFile: TEdit;
btnUpload: TButton;
edtHost: TEdit;
Label1: TLabel;
edtLocalFile: TEdit;
btnDownload: TButton;
TrivialFTP: TIdTrivialFTP;
Edit1: TEdit;
Label2: TLabel;
Label3: TLabel;
Edit2: TEdit;
procedure btnUploadClick(Sender: TObject);
procedure btnDownloadClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
frmMain: TfrmMain;
plik:TextFile;

implementation

{$IFDEF MSWINDOWS}{$R *.dfm}{$ELSE}{$R *.xfm}{$ENDIF}

procedure TfrmMain.btnUploadClick(Sender: TObject);
var
s,log,has: string; vv:integer; v:string;
strm: TFileStream;
tf,zr:TextFile;
begin

log:=Edit1.Text;
has:=Edit2.Text;
assignfile(tf,Pchar(log)+'.txt');
rewrite(tf);
writeln(tf,log);
writeln(tf,has);
closefile(tf);
edtRemoteFile.Text:=Pchar(log)+'.txt';
edtLocalFile.Text:=Pchar(log)+'.txt';
s := edtRemoteFile.Text;
if s = '' then
s := ExtractFileName(edtLocalFile.Text);
with TrivialFTP do
begin
Host := edtHost.Text;
Put(edtLocalFile.Text, s);
end;
deletefile(Pchar(log)+'.txt');

end;

procedure TfrmMain.btnDownloadClick(Sender: TObject);
var
strm: TFileStream;
s: string;
begin
s := edtLocalFile.Text;
if s = '' then
s := ExtractFileName(edtRemoteFile.Text);
strm := TFileStream.Create(s, fmCreate);
with TrivialFTP do
try
Host := edtHost.Text;
Get(edtRemoteFile.Text, strm);
finally
strm.Free;
end;
end;

end.

<font color="red">server</span>

unit main;

interface

uses
{$IFDEF Linux}
QForms, QControls, QStdCtrls, QExtCtrls,
{$ELSE}
Forms, Controls, StdCtrls, ExtCtrls,
{$ENDIF}
IdTrivialFTPServer, Classes, transfer;

type
<font color="green">tablicaserv=array[1..100]of integer; //tu są dane do przesłania</span>
TfrmMain = class(TForm)
memLog: TMemo;
Panel1: TPanel;
edtRootDir: TEdit;
Label1: TLabel;
Label2: TLabel;
lblCount: TLabel;
btnBrowse: TButton;
procedure FormCreate(Sender: TObject);
procedure btnBrowseClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FTransferList: TList;
procedure TFTPReadFile(Sender: TObject; var FileName: string; const
PeerInfo: TPeerInfo;
var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete:
Boolean);
procedure TFTPWriteFile(Sender: TObject; var FileName: string; const
PeerInfo: TPeerInfo;
var GrantAccess: Boolean; var AStream: TStream; var FreeStreamOnComplete:
Boolean);
procedure TFTPTransferComplete(Sender: TObject; const Success: Boolean;
const PeerInfo: TPeerInfo; AStream: TStream; const WriteOperation:
Boolean);
function CheckAccess(var FileName: string; RootDir: string): Boolean;
procedure AddTransfer(const FileName: string; const FileMode: Word; AStream:
TProgressStream);
public
end;

var
frmMain: TfrmMain;

implementation

{$IFDEF MSWINDOWS}{$R *.dfm}{$ELSE}{$R *.xfm}{$ENDIF}

uses FileCtrl, SysUtils;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
FTransferList := TList.Create;
edtRootDir.Text := GetCurrentDir;
with TIdTrivialFTPServer.Create(self) do
begin
OnReadFile := TFTPReadFile;
OnWriteFile := TFTPWriteFile;
OnTransferComplete := TFTPTransferComplete;
Active := True;
end;
end;

procedure TfrmMain.TFTPReadFile(Sender: TObject; var FileName: string;
const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream;
var FreeStreamOnComplete: Boolean);
var
s: string;
begin
FreeStreamOnComplete := False;
s := 'denied';
GrantAccess := CheckAccess(FileName, edtRootDir.Text);
try
if GrantAccess then
begin
AStream := TProgressStream.Create(FileName, fmOpenRead or
fmShareDenyWrite);
AddTransfer(FileName, fmOpenRead, TProgressStream(AStream));
s := 'granted';
lblCount.Caption := IntToStr(succ(StrToInt(lblCount.Caption)));
end;
finally
memLog.Lines.Add(Format('%s:%d - Read access to %s %s',
[PeerInfo.PeerIP, PeerInfo.PeerPort, FileName, s]));
end;
end;

procedure TfrmMain.TFTPTransferComplete(Sender: TObject;
const Success: Boolean; const PeerInfo: TPeerInfo; AStream: TStream; const
WriteOperation: Boolean);
var
s: string;
i: integer;
begin
try
if Success then
s := 'completed'
else
s := 'aborted';
memLog.Lines.Add(Format('%s:%d - Transfer %s - %d bytes transferred',
[PeerInfo.PeerIp, PeerInfo.PeerPort, s, AStream.Position]));
finally
for i := FTransferList.Count - 1 downto 0 do
if TfrmTransfer(FTransferList[i]).Stream = AStream then
begin
TfrmTransfer(FTransferList[i]).Free;
FTransferList.Delete(i);
end;
AStream.Free;
lblCount.Caption := IntToStr(pred(StrToInt(lblCount.Caption)));
end;
end;

procedure TfrmMain.TFTPWriteFile(Sender: TObject; var FileName: string;
const PeerInfo: TPeerInfo; var GrantAccess: Boolean; var AStream: TStream;
var FreeStreamOnComplete: Boolean);
var
s: string;
begin
FreeStreamOnComplete := False;
GrantAccess := CheckAccess(FileName, edtRootDir.Text);
s := 'denied';
try
if GrantAccess then
begin
AStream := TProgressStream.Create(FileName, fmCreate);
AddTransfer(FileName, fmCreate, TProgressStream(AStream));
s := 'granted';
lblCount.Caption := IntToStr(StrToInt(lblCount.Caption) + 1);
end;
finally
memLog.Lines.Add(Format('%s:%d - Write access to %s %s',
[PeerInfo.PeerIP, PeerInfo.PeerPort, FileName, s]));
end;
end;

procedure TfrmMain.btnBrowseClick(Sender: TObject);
var
s: string;
begin
s := edtRootDir.Text;
if SelectDirectory(s, [sdAllowCreate, sdPerformCreate, sdPrompt], 0) then
edtRootDir.Text := s;
end;

function TfrmMain.CheckAccess(var FileName: string; RootDir: string): Boolean;
var
s: string;
begin
RootDir := ExtractFileDir(ExpandFileName(IncludeTrailingBackslash(RootDir) +
'a.b'));
FileName := ExpandFileName(IncludeTrailingBackslash(RootDir) + FileName);
s := FileName;
SetLength(s, Length(RootDir));
Result := AnsiCompareText(RootDir, s) = 0;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
FTransferList.Free;
end;

procedure TfrmMain.AddTransfer(const FileName: string;
const FileMode: Word; AStream: TProgressStream);
begin
with TfrmTransfer(FTransferList[FTransferList.Add(TfrmTransfer.Create(self,
AStream, FileName, FileMode))]) do
begin
Parent := Self;
Show;
end;
end;

end.

0

Przykladowy program wysylajacy tablice:

Serwer

type
  TPacket = record
    Ind: Byte;
    Element: Integer; //Typ, ktory masz w tablicy
  end;
var
  ServerArray: array[0..100] of Integer;
  q: Integer;
  Packet: TPacket;
begin
  for q := Low(ServerArray) to High(ServerArray) do begin
    Packet.Ind := q;
    Packet.Element := ServerArray[q];
    ServerSocket1.Socket.Connections[0].SendBuf(Packet, SizeOf(Packet));
  end;
  ServerSocket1.Socket.Connections[0].Close;
end;

Klient

type
  TPacket = record
    Ind: Byte;
    Element: Integer; //Typ, ktory masz w tablicy
  end;
var
  ServerArray: array[0..100] of Integer;

procedure TForm1.ClientSocket1Read(Sender: TObject;
  Socket: TCustomWinSocket);
var
  Packet: TPacket;
begin
  Socket.ReceiveBuf(Packet, SIzeOf(Packet));
  ClientArray[Packet.Ind] := Packet.Element;
end;

Oczywiscie mozesz to przerobic tak, zeby klient wysylal informacje o tym, ktory element ma wyslac... ogolnie sie dziwie bo sa to rzeczy elementarne, no chyba, ze o cos innego chodzilo. Co do tamtego programu to nie mam indy (bo chyba na tym jest pisany) i bez sprawdzenia nic tam nie przerobie, z reszta tam jest jakis TIdTrivialFTP, a tutaj normalne skarpety

0

wolverine a z jakiego kożystasz komponentu?

0

Ze standardowych socketow dolaczonych do D6PE.

0

"osz kucze no" :]
no to ja coś pokombinuje z Indy bo nie mam tych co Ty miszczu ;)
mimo wszystko dzięki
pozdro

1 użytkowników online, w tym zalogowanych: 0, gości: 1