Board index » delphi » BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!

BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!

Hy!

I'm using TIdTCPServer and TIdTCPClient with Interbase.
My Server-Programm is managing commands from my Client-Programm.

My Server-Programm:
type
    TClientFM=class(TObject)
    public
        dm:Tdm; // Tdm=class(TDataModule)
    end;
....

procedure TMain.IdTCPServerConnect(AThread:TIdPeerThread);
var aItem:TClientFM;
begin
    aItem:=TClientFM.Create();
    aItem.dm:=Tdm.Create(...);
    AThread.Data:=Pointer(aItem);
end;

procedure TMain.IDTCPServerExecute(AThread:TIdPeerThread);
var
    aItem:TClientFM;
    cmd:string;
begin
    cmd:=AThread.Connection.Readln(ATermin);
    aItem:=Pointer(AThread.Data);
    aItem.dm.DoSomething(AThread) -> for Example open a view and send
FieldVals to Client
end;

procedure Tdm.DoSomething(AThread:TIdPeerThread);
begin
    view.open;view.first;
    while not view.eof do
    begin
        str:=CreateRecordLn(view); // only creates a string with FieldVals
        AThread.Connection.Write(str);
        view.next;
    end; //// ****
    view.close;
end;

This works fine with one client and small views.
But if the view is very big (only for testing about 6000 records), my
server-programm hang up AFTER Flushing Buffer (See ****).
And if second client is connecting to the server, and the first has not
finished
writing over the Connection, the next AThread.Connection.Write()
causes Invalide Pointer Operation.

Working with OpenWriteBuffer, WriteBuffer, FlushWriteBuffer and
CloseWriteBuffer
has same effect.

PLEASE HELP !!!!

 

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


Can you tell use what version of Indy you are using?

--
eng. Doychin Bondzhev - Team Indy
doyc...@dsoft-bg.com
DdSoft-Bulgaria
http://www.dsoft-bg.com

"Ing. Schardl robert" <robert.scha...@asystem.at> wrote in message
news:3b4a9bd9_1@dnews...

Quote
> Hy!

> I'm using TIdTCPServer and TIdTCPClient with Interbase.
> My Server-Programm is managing commands from my Client-Programm.

> My Server-Programm:
> type
>     TClientFM=class(TObject)
>     public
>         dm:Tdm; // Tdm=class(TDataModule)
>     end;
> ....

> procedure TMain.IdTCPServerConnect(AThread:TIdPeerThread);
> var aItem:TClientFM;
> begin
>     aItem:=TClientFM.Create();
>     aItem.dm:=Tdm.Create(...);
>     AThread.Data:=Pointer(aItem);
> end;

> procedure TMain.IDTCPServerExecute(AThread:TIdPeerThread);
> var
>     aItem:TClientFM;
>     cmd:string;
> begin
>     cmd:=AThread.Connection.Readln(ATermin);
>     aItem:=Pointer(AThread.Data);
>     aItem.dm.DoSomething(AThread) -> for Example open a view and send
> FieldVals to Client
> end;

> procedure Tdm.DoSomething(AThread:TIdPeerThread);
> begin
>     view.open;view.first;
>     while not view.eof do
>     begin
>         str:=CreateRecordLn(view); // only creates a string with FieldVals
>         AThread.Connection.Write(str);
>         view.next;
>     end; //// ****
>     view.close;
> end;

> This works fine with one client and small views.
> But if the view is very big (only for testing about 6000 records), my
> server-programm hang up AFTER Flushing Buffer (See ****).
> And if second client is connecting to the server, and the first has not
> finished
> writing over the Connection, the next AThread.Connection.Write()
> causes Invalide Pointer Operation.

> Working with OpenWriteBuffer, WriteBuffer, FlushWriteBuffer and
> CloseWriteBuffer
> has same effect.

> PLEASE HELP !!!!

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


8.00.23

"Doychin Bondzhev" <doyc...@dsoft-bg.com> schrieb im Newsbeitrag
news:3b4a9cbc_1@dnews...

Quote
> Can you tell use what version of Indy you are using?

> --
> eng. Doychin Bondzhev - Team Indy
> doyc...@dsoft-bg.com
> DdSoft-Bulgaria
> http://www.dsoft-bg.com

> "Ing. Schardl robert" <robert.scha...@asystem.at> wrote in message
> news:3b4a9bd9_1@dnews...
> > Hy!

> > I'm using TIdTCPServer and TIdTCPClient with Interbase.
> > My Server-Programm is managing commands from my Client-Programm.

> > My Server-Programm:
> > type
> >     TClientFM=class(TObject)
> >     public
> >         dm:Tdm; // Tdm=class(TDataModule)
> >     end;
> > ....

> > procedure TMain.IdTCPServerConnect(AThread:TIdPeerThread);
> > var aItem:TClientFM;
> > begin
> >     aItem:=TClientFM.Create();
> >     aItem.dm:=Tdm.Create(...);
> >     AThread.Data:=Pointer(aItem);
> > end;

> > procedure TMain.IDTCPServerExecute(AThread:TIdPeerThread);
> > var
> >     aItem:TClientFM;
> >     cmd:string;
> > begin
> >     cmd:=AThread.Connection.Readln(ATermin);
> >     aItem:=Pointer(AThread.Data);
> >     aItem.dm.DoSomething(AThread) -> for Example open a view and send
> > FieldVals to Client
> > end;

> > procedure Tdm.DoSomething(AThread:TIdPeerThread);
> > begin
> >     view.open;view.first;
> >     while not view.eof do
> >     begin
> >         str:=CreateRecordLn(view); // only creates a string with
FieldVals
> >         AThread.Connection.Write(str);
> >         view.next;
> >     end; //// ****
> >     view.close;
> > end;

> > This works fine with one client and small views.
> > But if the view is very big (only for testing about 6000 records), my
> > server-programm hang up AFTER Flushing Buffer (See ****).
> > And if second client is connecting to the server, and the first has not
> > finished
> > writing over the Connection, the next AThread.Connection.Write()
> > causes Invalide Pointer Operation.

> > Working with OpenWriteBuffer, WriteBuffer, FlushWriteBuffer and
> > CloseWriteBuffer
> > has same effect.

> > PLEASE HELP !!!!

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


"Ing. Schardl robert" <robert.scha...@asystem.at> wrote in message
news:3b4a9bd9_1@dnews...

Quote
> procedure TMain.IDTCPServerExecute(AThread:TIdPeerThread);
> var
>     aItem:TClientFM;
>     cmd:string;
> begin
>     cmd:=AThread.Connection.Readln(ATermin);
>     aItem:=Pointer(AThread.Data);
>     aItem.dm.DoSomething(AThread) -> for Example open a view and send
> FieldVals to Client
> end;

are you sure that calling aItem.dm.DoSomething is 100% threadsafe?

Keep in mind that IDTCPServerExecute runs in the context of AThread -- not
your main thread.

Quote
> And if second client is connecting to the server, and the first has not
> finished
> writing over the Connection, the next AThread.Connection.Write()
> causes Invalide Pointer Operation.

Because from what you describe here, thread(un)safety is the first thing
that springs to mind.

--
Rune

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


Quote
> Keep in mind that IDTCPServerExecute runs in the context of AThread -- not
> your main thread.

This is because i create a new aItem:TClientFM in Connect and save the
Pointer in AThread.Data !
On executing i get aItem:TClientFM from AThread.Data !
On every client-connect i create a new TClientFM.

procedure IDTCPServerConnect(AThread:TIdPeerThread);
var aItem:TClientFM;
begin
aItem:=TClientFM.Create;
AThread.Data:=Pointer(aItem);
end;

Because Connect also runs in the context of AThread, aItem will be created
within the Thread,
or am i wrong ??

"Rune Moberg" <rmob...@arxi.no> schrieb im Newsbeitrag
news:3b4ac417_1@dnews...

Quote
> "Ing. Schardl robert" <robert.scha...@asystem.at> wrote in message
> news:3b4a9bd9_1@dnews...
> > procedure TMain.IDTCPServerExecute(AThread:TIdPeerThread);
> > var
> >     aItem:TClientFM;
> >     cmd:string;
> > begin
> >     cmd:=AThread.Connection.Readln(ATermin);
> >     aItem:=Pointer(AThread.Data);
> >     aItem.dm.DoSomething(AThread) -> for Example open a view and send
> > FieldVals to Client
> > end;

> are you sure that calling aItem.dm.DoSomething is 100% threadsafe?

> Keep in mind that IDTCPServerExecute runs in the context of AThread -- not
> your main thread.

> > And if second client is connecting to the server, and the first has not
> > finished
> > writing over the Connection, the next AThread.Connection.Write()
> > causes Invalide Pointer Operation.

> Because from what you describe here, thread(un)safety is the first thing
> that springs to mind.

> --
> Rune

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


"Ing. Schardl robert" <robert.scha...@asystem.at> wrote in message
news:3b4ad15a_1@dnews...

Quote
> Because Connect also runs in the context of AThread, aItem will be created
> within the Thread,

That might not matter one iota.

If e.g. you're using BDE, you still have to have a separate TSession for
each thread. That's just one example of a common trap. I have no idea of
what your datamodule looks like, but you might want to read the docs of the
database components you're using to make sure they are threadsafe. Both ADO
and IBX should be fine though (to the best of my knowledge -- I might be
mistaken!).

In addition if your datamodule contains other components/pieces of code that
accesses global resources, then of course that too constitutes a problem.

Your problem is currently very complex and you should narrow it down. Try to
create a huge block of data and just transmit that instead of instantiating
the datamodule. See if the problem really is transferring huge amounts of
data, or if it's related to the datamodule somehow.

--
Rune

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


"Ing. Schardl robert" <robert.scha...@asystem.at> schrieb im Newsbeitrag
news:3b4a9bd9_1@dnews...

Quote
> procedure TMain.IdTCPServerConnect(AThread:TIdPeerThread);
> var aItem:TClientFM;
> begin
>     aItem:=TClientFM.Create();
>     aItem.dm:=Tdm.Create(...);
>     AThread.Data:=Pointer(aItem);
> end;

AThread.Data is very dangerous! I didn't read all your code, but this is a
detail I have to point out.

AThread.Data is freed in the destructor of TIdPeerThread, although the
thread didn't create it. You have to set Data:=nil if you want to use your
aItem after the destruction of the thread.

This is really {*word*193} (but documented, if you read carefully) behaviour.
Some less experienced programmers might disagree, but I call it a bug. Maybe
some Indy team member can explain it, but the last time I asked there was no
response...

---
Oliver

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


Quote
"Oliver Kraheck" <oli...@REMOVETHISkraheck.de> wrote in message

news:3b4b0bdc_2@dnews...

Quote
> AThread.Data is very dangerous!

If you feel it is dangerous, then don't use it.  You can always subclass
TIdThread, and
provide a property that is allocated in the constructor and freed in the
destructor.

Destroy is virtual, so you can override the Destroy behavior.  But you'll
have these object references{*word*154} around after the Thread is freed.

Quote
> Some less experienced programmers might disagree, but I call it a bug.
Maybe
> some Indy team member can explain it, but the last time I asked there was
no
> response...

I didn't write TIdThread, but my take on it is that it's a way to avoid
forcing the programmer to subclass TIdThread just to provide data storage.
You can use the OnTerminate event handler to set Data := Nil to avoid the
issue, or use a descendant class as described above.

hth...

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


TIdThread.Data must not be assigned !!!
TIdThread.Data is TObject.
A TObject is a pointer ( -->> TObject.Create())
If you set TIdThread.Data:=AThread, Data holds the Pointer to the
AThread-Object.
In this case, AThread must be assigned.

TIdThread.Data:=AThread is only used to store the pointer of AThread to find
it very fast.
I've done this with Collections before, where a CollectionItem is a
ClientConnection.

type
TSimpleClient=class(TCollectionItem)
public
dm:Tdm; // TDataModule
Thread:Pointer;
end;

aItem:=pSimpleColl.Add as TSimpleClient;
aItem.Thread:=Pointer(AThread);

--------->>>>>>>>>>
Now i've solved the problem with large data.
The other problem is, that he second thread is executed after the first
finished.
Both Threads are running separatly and don't share any data.
TCPServerExecute only calls aItem.DoSomething, where aItem is "See mails
above".
Do i have to synchronise all the threads with TCPServer??

I had no problems with TServerClientThread.ClientExecute, but the same with
Indy don't work like the Version
with TServerClientThread. Have i forgotten something ??

Thanks.

"Oliver Kraheck" <oli...@REMOVETHISkraheck.de> schrieb im Newsbeitrag
news:3b4b0bdc_2@dnews...

Quote

> "Ing. Schardl robert" <robert.scha...@asystem.at> schrieb im Newsbeitrag
> news:3b4a9bd9_1@dnews...
> > procedure TMain.IdTCPServerConnect(AThread:TIdPeerThread);
> > var aItem:TClientFM;
> > begin
> >     aItem:=TClientFM.Create();
> >     aItem.dm:=Tdm.Create(...);
> >     AThread.Data:=Pointer(aItem);
> > end;

> AThread.Data is very dangerous! I didn't read all your code, but this is a
> detail I have to point out.

> AThread.Data is freed in the destructor of TIdPeerThread, although the
> thread didn't create it. You have to set Data:=nil if you want to use your
> aItem after the destruction of the thread.

> This is really {*word*193} (but documented, if you read carefully) behaviour.
> Some less experienced programmers might disagree, but I call it a bug.
Maybe
> some Indy team member can explain it, but the last time I asked there was
no
> response...

> ---
> Oliver

Re:BIG PROBLEMS in sending LOT OF DATA with TIdTCPServer/Client PLEASE HELP ME !!!!


A other programmer also works with Indy and has the same problems.
But he has another problem:
INVALIDE POINTER OPERATION in first Thread on writing over
AThread.Connection.Writeln(), after a second Thread executes ->
TIdTCPServerExecute()
and the first has not already finished.
He also uses AThread.Data=Pointer(aItem); -->> aItem:=Pointer(AThread.Data);

 - first Thread -> AThread.Connection.Writeln();
 - first Thread -> AThread.Connection.Writeln();
 - first Thread -> AThread.Connection.Writeln();
 - sec. Thread -> AThread.Connection.Writeln();
 - INVALIDE POINTER OPERATION -> first Thread

Has anybody an idea???

"Oliver Kraheck" <oli...@REMOVETHISkraheck.de> schrieb im Newsbeitrag
news:3b4b0bdc_2@dnews...

Quote

> "Ing. Schardl robert" <robert.scha...@asystem.at> schrieb im Newsbeitrag
> news:3b4a9bd9_1@dnews...
> > procedure TMain.IdTCPServerConnect(AThread:TIdPeerThread);
> > var aItem:TClientFM;
> > begin
> >     aItem:=TClientFM.Create();
> >     aItem.dm:=Tdm.Create(...);
> >     AThread.Data:=Pointer(aItem);
> > end;

> AThread.Data is very dangerous! I didn't read all your code, but this is a
> detail I have to point out.

> AThread.Data is freed in the destructor of TIdPeerThread, although the
> thread didn't create it. You have to set Data:=nil if you want to use your
> aItem after the destruction of the thread.

> This is really {*word*193} (but documented, if you read carefully) behaviour.
> Some less experienced programmers might disagree, but I call it a bug.
Maybe
> some Indy team member can explain it, but the last time I asked there was
no
> response...

> ---
> Oliver

Other Threads