🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.internet.socket
9 messages
9 total messages Started by Stefano Bonifazi Sat, 23 Dec 2006 14:37
TClientSocket in consolle applications
#1661
Author: Stefano Bonifazi
Date: Sat, 23 Dec 2006 14:37
21 lines
1806 bytes
Hello everybody!
  I need to wrap some basic functionality of TClientSocket inside a dll 
for reusing it in a not borland console application.
The dll is developed with BCB6, so I can include there all the VCL code 
I like!
Inside the dll I created 3 basic function:
-the first simply create an instance of TClientSocket and connetc it to 
the remote server I need.
-the second uses the Socket->SendText function for delivering strings to 
the server it is connected to
-the third simply disconnect the client and destroy the TClientSocket 
instance

If I load the dll dinamically from a VCL application all works fine, I 
can connect my client to the server, send that my texts and then 
disconnect form it!
If I load the dll dinamically from a consolle application only Connect 
works! I may think that there is something related to Windows messages, 
how can I make it work even with consolle applications?
  Thank U very much in advance!
Stefano B.
Re: TClientSocket in consolle applications
#1669
Author: Bob Gonder
Date: Sat, 23 Dec 2006 17:05
14 lines
1637 bytes
Stefano Bonifazi wrote:

>If I load the dll dinamically from a consolle application only Connect 
>works! I may think that there is something related to Windows messages, 
>how can I make it work even with consolle applications?

You might be able to have your connect function spawn a new thread to
pump messages (create a hidden window to receive messages). The
disconnect function could then send a private message for the thread
to terminate (WM_CLOSE the hidden window).

Or set it up to work in blocking mode.

Or maybe you don't have vcl and bpl dlls available for the console?
Re: TClientSocket in consolle applications
#1673
Author: Stefano Bonifazi
Date: Sat, 23 Dec 2006 18:18
18 lines
1512 bytes
Thank You very much for Ur reply!!


Bob Gonder wrote:
> You might be able to have your connect function spawn a new thread to
> pump messages (create a hidden window to receive messages). The
> disconnect function could then send a private message for the thread
> to terminate (WM_CLOSE the hidden window).

Please could U be so kind to show how to do? or a link where it is showed?

> Or maybe you don't have vcl and bpl dlls available for the console?

well I can deploy the required bpls I think!

Thank U again,
Regards,
Stefano B.
Re: TClientSocket in consolle applications
#1675
Author: Bob Gonder
Date: Sun, 24 Dec 2006 01:32
102 lines
3979 bytes
Stefano Bonifazi wrote:

>> You might be able to have your connect function spawn a new thread to
>> pump messages (create a hidden window to receive messages). The
>> disconnect function could then send a private message for the thread
>> to terminate (WM_CLOSE the hidden window).
>
>Please could U be so kind to show how to do? or a link where it is showed?

I was going to show the Charles Petzold way (plain WinAPI), but VCL is
probably going to be easier (not that I know what I'm doing in VCL....
In fact, I'm pretty sure this won't work as written, but this is where
I would start working.)

Probably easiest is to have a TApplication::Main1 in your dll.
Set the form's visibility property to hidden.
Drop a TClientSocket on the form.
Also create a thread to run the "application-form".

class TMyThread : public TThread
{
private:
protected:
  void __fastcall Execute();
public:
__fastcall TMyThread(bool CreateSuspended);
};


TMain1*	Main1 = NULL;
TMyThread *MyThread;


__fastcall TMyThread::TMyThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}

void __fastcall TMyThread::Execute()
{
#if ThisWorks
	Main1 = new TMain1( NULL );
	Main1->Hide();
	while( ! terminated )
	{
		//process all outstanding messages
		Main1->ProcessMessages();	
		//slow it down so the thread doesn't hit so hard
		Sleep(0);
	};
	delete Main1; //not sure about this
#else
                Application->Initialize();
                Application->CreateForm(__classid(TMain1), &Main1);
                Application->Run();
#endif
	Main1 = NULL;
}


You wanted a simple 3-function interface, so....
The DLL interfaces:

MyConnect( AnsiString &Host )
{	MyThread = new TMyThread(false);
	while( Main1 == NULL )	/* could change to event semiphore */
		Sleep( 10 );	/* to avoid the dreaded Sleep() */
	Main1->Client->Connect( Host );
}
MySend( AnsiString &Message )
{	if( Main1 )
	Main1->Client->Send( Message );
}
MyDisconnect()
{	if( Main1 )
	Main1->Client->Disconnect();
}


Then inside the Client Disconnect, at the very end...
	Main1->Close();
#if ThisWorks
	MyThread->Terminate();
#else
	//thread self-terminates
#endif
which should allow the thread to exit.


I would be tempted to create and destroy the form in the dll entry
point (see DllMain in help) instead of the user interface, using the
DLL_PROCESS_ATTACH and  DLL_PROCESS_DETACH flags to determine
if creating or destroying the form.  That should help eliminate some
of the race conditions in the above code, and also removes specialized
code from the TClientSocket methods.


Now that I look at this, it looks like swatting a gnat with a
thermonuclear device.  In actuallity, I've done all this in plain
WinAPI with blocking WinSocks, and it didn't turn out to be that bad.
Bringing in the entire VCL just to run one socket seems a tad
overkill.
Re: TClientSocket in consolle applications
#1527
Author: Stefano Bonifazi
Date: Sun, 24 Dec 2006 12:17
44 lines
2284 bytes
Thank U again for Ur help!

Bob Gonder wrote:
> I was going to show the Charles Petzold way (plain WinAPI), 

Please do!

> Probably easiest is to have a TApplication::Main1 in your dll.

what do U mean by Main1? Is that a form?


> void __fastcall TMyThread::Execute()
> {
> #if ThisWorks
> 	Main1 = new TMain1( NULL );
> 	Main1->Hide();
> 	while( ! terminated )
> 	{
> 		//process all outstanding messages
> 		Main1->ProcessMessages();	

if Main1 is a form then it has not ProcessMessages() ... that is a 
TApplication method!


> 		//slow it down so the thread doesn't hit so hard
> 		Sleep(0);
> 	};
> 	delete Main1; //not sure about this
> #else
>                 Application->Initialize();
>                 Application->CreateForm(__classid(TMain1), &Main1);
>                 Application->Run();

This seems to work, and the form receives messages correctly! But then 
Application never stops even if I call Application->Terminate() from a 
dll function, or I call MyThread->Terminate() or I close manually the 
form... So an Exception is always thrown when my dll is unloaded it says 
"System error. Code 5. Access forbidden" :(

What can I do?
Thank U again!
Stefano b.
Re: TClientSocket in consolle applications
#1528
Author: Bob Gonder
Date: Sun, 24 Dec 2006 19:06
25 lines
1885 bytes
Stefano Bonifazi wrote:

>> I was going to show the Charles Petzold way (plain WinAPI), 
>
>Please do!

There is a link in here, under Programming Windows 95
http://www.charlespetzold.com/books.html

I took a random look at Chapter 3, sysmets1.c, and it has what appears
to be a fully functional WinMain and WinProc.
Strip the function and paramters off  WinMain, and inject the naked
function into a thread
Adjust the case() statements in the WinProc to handle the messages
your TClient requires.

>> void __fastcall TMyThread::Execute()
>> {

naked WinMain function code goes here

>> }

Also, I'm sure there are more involved examples in the later chapters,
if you are interested in WinAPI programming.
Re: TClientSocket in consolle applications
#1529
Author: Stefano Bonifazi
Date: Sun, 24 Dec 2006 19:39
27 lines
2334 bytes
Hi again!And thank U for all Ur support!!

> I took a random look at Chapter 3, sysmets1.c, and it has what appears
> to be a fully functional WinMain and WinProc.
> Strip the function and paramters off  WinMain, and inject the naked
> function into a thread
I think that can be more easily done by the VCL

AllocateHWnd(MyWndProc)

> Adjust the case() statements in the WinProc to handle the messages
> your TClient requires.

I think that is the matter!!
I only would like my TClientSocket to use the new messages pool I 
create, I don't want to sit to rewrite what it should do for every 
message it manages .. I even don't know them... I should study all the 
scktcomp to know those..and maybe than I should have access to some 
private method of TClientSocket ancestors :( I think there has to be an 
easier way to do! The way  U proposed with TApplication worked, and the 
forms opened had their messages posted fine.. but then the application 
instance did not close.. and an exception was thrown when I unloaded the 
dll :(

I thank U again.. and wish U Merry Christmas!
Regards,
Stefano B.
Re: TClientSocket in consolle applications
#1530
Author: Remy Lebeau (TeamB)
Date: Mon, 25 Dec 2006 20:49
15 lines
1432 bytes
"Stefano Bonifazi" <stefboombastic@email.it> wrote in message
news:458d3f0d@newsgroups.borland.com...

> If I load the dll dinamically from a consolle application only Connect
> works! I may think that there is something related to Windows messages,
> how can I make it work even with consolle applications?

If you are using the TClientSocket in non-blocking mode, then the console
application needs an active message queue in the thread that is calling the
DLL.  Otherwise, you will have to use the TClientSocket in blocking mode
instead so that no messages are used.


Gambit
Re: TClientSocket in consolle applications
#1532
Author: Remy Lebeau (TeamB)
Date: Mon, 25 Dec 2006 20:49
17 lines
1426 bytes
"Bob Gonder" <notbg@notmindspring.invalid> wrote in message
news:rklqo2pjrnk6arfk43f665lq65djkr55vq@4ax.com...

> You might be able to have your connect function spawn a new thread
> to pump messages (create a hidden window to receive messages).

That will not work.  A thread cannot receive messages that belong to another
thread.  The TClientSocket belongs to whatever thread actually creates it,
so only that thread can receive the messages.

> Or set it up to work in blocking mode.

That would be the way to go.


Gambit
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads