Thread View: borland.public.cppbuilder.internet.socket
11 messages
11 total messages
Started by Darlington ADIBE
Thu, 17 Nov 2005 07:27
Indy TCP "Wait for Reply"
Author: Darlington ADIBE
Date: Thu, 17 Nov 2005 07:27
Date: Thu, 17 Nov 2005 07:27
26 lines
2110 bytes
2110 bytes
Hi All, Am doing an App using the indy TCP server/Client componnet and i need an adivce on how best to handle the situation am about the describle below. the tcp client is in a COM object with the following methods Authenticat, Send, etc...., when the host client app (exe using my COM API) calls the authenticate method, my com obj tries to connect to a TCP Server on a remote machine, if connected it send the uid and pwd parameter pass through authenticate to the server msg format "#AUTHEN#xxxx#xxxx# where AUTHEN = do Authentication, first xxxx = Username, second xxxx = password, the server check the username/password pairs in a database, if correct it sends back #AUTHEN#OK# if not it sends #AUTHEN#ERR#xxxxxxx# where xxxxx = reason of then Error. The situation above i have don so far, the issue is in the client end, when the exe call the com api Authenticate(uid, pwd), I don't want the method (authenticate) to return untill the server send back #AUTHEN#OK# or #AUTHEN#ERR#xxxxxx# or a RTimeout property of the COM obj is reached RTimeout is the Rececive Time Out propety of the con obj that indicate how long to wait before expected receive times out. Any profession advice on how to implement this "wait for reply" issue Darl.
Re: Indy TCP "Wait for Reply"
Author: Remy Lebeau (TeamB)
Date: Thu, 17 Nov 2005 18:08
Date: Thu, 17 Nov 2005 18:08
68 lines
2862 bytes
2862 bytes
"Darlington ADIBE" <bcb@triative.com> wrote in message
news:437c328b@newsgroups.borland.com...
> Any profession advice on how to implement this "wait for reply" issue
Indy already implements all of that for you. Simply read from the socket
immediately after you write to it. The reading will not return until data
is actually received, or a timeout/error occurs. For example:
HRESULT __stdcall TMyComObjImpl::Authenticate(BSTR uid, BSTR pwd)
{
try
{
AnsiString Cmd;
AnsiString Response;
AnsiString Status;
Cmd.sprintf("#AUTHEN#%s#%s#", AnsiString(uid).c_str(),
AnsiString(pwd).c_str());
TCPClient->Connect(5000);
try
{
TCPClient->WriteLn(Cmd);
Response = TCPClient->ReadLn(LF, IdTimeoutDefault; -1);
Response.Delete(1,1);
if( Fetch(Response, "#") != "AUTHEN" )
throw Exception("Unknown response");
Status = Fetch(Response, "#");
if( Status != "OK" )
{
if( Status == "ERR" )
throw Exception("Authentication failed: " +
Fetch(Response, "#"));
else
throw Exception("Unknown response");
}
}
catch(const Exception &)
{
TCPClient->Disconnect();
throw;
}
}
catch(const Exception &e)
{
return Error(e.Message, IID_IMyComObj);
}
return S_OK;
}
HRESULT __stdcall TMyComObjImpl::get_RTimeout(long *Result)
{
*Result = TCPClient->ReadTimeout;
return S_OK;
}
HRESULT __stdcall TMyComObjImpl::set_RTimeout(long Value)
{
TCPClient->ReadTimeout = Value;
return S_OK;
}
Gambit
Re: Indy TCP "Wait for Reply"
Author: Darlington ADIBE
Date: Thu, 17 Nov 2005 18:58
Date: Thu, 17 Nov 2005 18:58
79 lines
3312 bytes
3312 bytes
Thank, looks perfect for what i needed. By the way 'Fetch' is it a BCB6
function or what?
Darl.
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:437cc79a$1@newsgroups.borland.com...
>
> "Darlington ADIBE" <bcb@triative.com> wrote in message
> news:437c328b@newsgroups.borland.com...
>
> > Any profession advice on how to implement this "wait for reply" issue
>
> Indy already implements all of that for you. Simply read from the socket
> immediately after you write to it. The reading will not return until data
> is actually received, or a timeout/error occurs. For example:
>
> HRESULT __stdcall TMyComObjImpl::Authenticate(BSTR uid, BSTR pwd)
> {
> try
> {
> AnsiString Cmd;
> AnsiString Response;
> AnsiString Status;
>
> Cmd.sprintf("#AUTHEN#%s#%s#", AnsiString(uid).c_str(),
> AnsiString(pwd).c_str());
>
> TCPClient->Connect(5000);
> try
> {
> TCPClient->WriteLn(Cmd);
> Response = TCPClient->ReadLn(LF, IdTimeoutDefault; -1);
>
> Response.Delete(1,1);
> if( Fetch(Response, "#") != "AUTHEN" )
> throw Exception("Unknown response");
>
> Status = Fetch(Response, "#");
> if( Status != "OK" )
> {
> if( Status == "ERR" )
> throw Exception("Authentication failed: " +
> Fetch(Response, "#"));
> else
> throw Exception("Unknown response");
> }
> }
> catch(const Exception &)
> {
> TCPClient->Disconnect();
> throw;
> }
> }
> catch(const Exception &e)
> {
> return Error(e.Message, IID_IMyComObj);
> }
> return S_OK;
> }
>
> HRESULT __stdcall TMyComObjImpl::get_RTimeout(long *Result)
> {
> *Result = TCPClient->ReadTimeout;
> return S_OK;
> }
>
> HRESULT __stdcall TMyComObjImpl::set_RTimeout(long Value)
> {
> TCPClient->ReadTimeout = Value;
> return S_OK;
> }
>
>
> Gambit
>
>
>
Re: Indy TCP "Wait for Reply"
Author: Remy Lebeau (TeamB)
Date: Thu, 17 Nov 2005 21:18
Date: Thu, 17 Nov 2005 21:18
11 lines
1254 bytes
1254 bytes
"Darlington ADIBE" <bcb@triative.com> wrote in message news:437cd28f@newsgroups.borland.com... > Thank, looks perfect for what i needed. By the way > 'Fetch' is it a BCB6 function or what? It is an Indy function, in the IdGlobal unit. Gambit
Re: Indy TCP "Wait for Reply"
Author: Darlington ADIBE
Date: Thu, 17 Nov 2005 21:48
Date: Thu, 17 Nov 2005 21:48
24 lines
1859 bytes
1859 bytes
Thank again. IdTCPClient or IdTCPServer doesn't have this property "ReadTimeout" and how do I change the default time as in tcpclient->ReadLn(LF, IdTimeoutDefault); how do i make the server to LF as line terminator and then change the default time value since ReadTimeout is not a valid property. Darl. "Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:437cf568$1@newsgroups.borland.com... > > "Darlington ADIBE" <bcb@triative.com> wrote in message > news:437cd28f@newsgroups.borland.com... > > > Thank, looks perfect for what i needed. By the way > > 'Fetch' is it a BCB6 function or what? > > It is an Indy function, in the IdGlobal unit. > > > Gambit > >
Re: Indy TCP "Wait for Reply"
Author: Remy Lebeau (TeamB)
Date: Thu, 17 Nov 2005 21:57
Date: Thu, 17 Nov 2005 21:57
15 lines
1529 bytes
1529 bytes
"Darlington ADIBE" <bcb@triative.com> wrote in message news:437cfa81@newsgroups.borland.com... > IdTCPClient or IdTCPServer doesn't have this property > "ReadTimeout" Yes, they do. It is a property of TIdTCPConnection in Indy 9 and of TIdIOHandler in Indy 10. If you don't have the property, then you must be using the version of Indy that ships with BCB6. That version of Indy is VERY old and no longer supported. You should seriously consider upgrading to a newer version. Gambit
Re: Indy TCP "Wait for Reply"
Author: Darlington ADIBE
Date: Fri, 18 Nov 2005 00:33
Date: Fri, 18 Nov 2005 00:33
31 lines
1994 bytes
1994 bytes
> Yes, they do. It is a property of TIdTCPConnection in Indy 9 and of
> TIdIOHandler in Indy 10. If you don't have the property, then you must be
> using the version of Indy that ships with BCB6. That version of Indy is
> VERY old and no longer supported. You should seriously consider upgrading
> to a newer version.
I have up graded to indy9.
and now my server doesn't work again i get an access voilation error in the
Execute Event
void __fastcall TForm1::tcpExecute(TIdPeerThread *AThread)
{
AnsiString cmd;
AnsiString request;
do{
request = AThread->Connection->ReadLn(LF, -2); <---- Error is thrown
here
cmd = Fetch(request, "#");
if(cmd == "AUTHEN") Authenticate(AThread, request);
} while(cmd != AnsiString("DISCONT"));
AThread->Connection->Disconnect();
}
I still don't see any property that allow me to change the default Line
Terminatior, that of ReadTimeout I saw
Darl.
Re: Indy TCP "Wait for Reply"
Author: Remy Lebeau (TeamB)
Date: Fri, 18 Nov 2005 01:44
Date: Fri, 18 Nov 2005 01:44
42 lines
2502 bytes
2502 bytes
"Darlington ADIBE" <bcb@triative.com> wrote in message
news:437d20f2@newsgroups.borland.com...
> I have up graded to indy9.
Which build, though?
> and now my server doesn't work again i get an
> access voilation error in the Execute Event
Your code should not be looping at all. The OnExecute event handler is
already looped internally by Indy. Just process a single command and then
exit the handler, ie:
void __fastcall TForm1::tcpExecute(TIdPeerThread *AThread)
{
AnsiString request = AThread->Connection->ReadLn(LF,
IdTimeoutDefault, -1);
request.Delete(1, 1);
AnsiString cmd = Fetch(request, "#");
if( cmd == "AUTHEN" )
Authenticate(AThread, request);
else if( cmd == "DISCONT" )
AThread->Connection->DisconnectSocket();
}
You might also consider using the CommandHandler collection instead of the
OnExecute event. The CommandHandler collection provides much automation
when it comes to parsing and processing textual commands.
> I still don't see any property that allow me to change the
> default Line Terminatior
There is no property for that. Simply specify the desired line terminator
when calling ReadLn(). That is what its first parameter is for:
AnsiString request =
AThread->Connection->ReadLn('YourLineDelimiterHere', IdTimeoutDefault, -1);
Gambit
Re: Indy TCP "Wait for Reply"
Author: Darlington ADIBE
Date: Fri, 18 Nov 2005 16:26
Date: Fri, 18 Nov 2005 16:26
59 lines
3100 bytes
3100 bytes
Remy thank alot,
Indy 9.0.17 was very helpful, the CommandHandler made my code very easy and
well structured, though am still to figure how to use the some other new
features
I give it Up for the Indy Team.
I hope DevStudio2006 will support Indy 10 (as in C++ )
Darl.
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:437d3195$1@newsgroups.borland.com...
>
> "Darlington ADIBE" <bcb@triative.com> wrote in message
> news:437d20f2@newsgroups.borland.com...
>
> > I have up graded to indy9.
>
> Which build, though?
>
> > and now my server doesn't work again i get an
> > access voilation error in the Execute Event
>
> Your code should not be looping at all. The OnExecute event handler is
> already looped internally by Indy. Just process a single command and then
> exit the handler, ie:
>
> void __fastcall TForm1::tcpExecute(TIdPeerThread *AThread)
> {
> AnsiString request = AThread->Connection->ReadLn(LF,
> IdTimeoutDefault, -1);
> request.Delete(1, 1);
> AnsiString cmd = Fetch(request, "#");
> if( cmd == "AUTHEN" )
> Authenticate(AThread, request);
> else if( cmd == "DISCONT" )
> AThread->Connection->DisconnectSocket();
> }
>
> You might also consider using the CommandHandler collection instead of the
> OnExecute event. The CommandHandler collection provides much automation
> when it comes to parsing and processing textual commands.
>
> > I still don't see any property that allow me to change the
> > default Line Terminatior
>
> There is no property for that. Simply specify the desired line terminator
> when calling ReadLn(). That is what its first parameter is for:
>
> AnsiString request =
> AThread->Connection->ReadLn('YourLineDelimiterHere',
IdTimeoutDefault, -1);
>
>
> Gambit
>
>
FYI
Author: Darlington ADIBE
Date: Fri, 18 Nov 2005 18:38
Date: Fri, 18 Nov 2005 18:38
16 lines
1563 bytes
1563 bytes
FYI: I tried a move my core funtions into my COM Obj, which mean I had to now manually include the nesesary header, since my COM have no Visual control. I notict that when you #include <IdTCPClient.hpp>, i get error that alot of variables was decleared early. on examination i noticed that both the winsock2.h and winsock.h was include along the IdTCPClient.hpp which is not the case if i had place the control on the Form directly. However i worked around it by #define _WINSOCKAPI_ just before #include <IdTCPClient.hpp> Am just wondering if I did some wrong along the line or if anybody have noticed this too.
Re: FYI
Author: Remy Lebeau (TeamB)
Date: Fri, 18 Nov 2005 19:54
Date: Fri, 18 Nov 2005 19:54
16 lines
1469 bytes
1469 bytes
"Darlington ADIBE" <bcb@triative.com> wrote in message news:437e1f49@newsgroups.borland.com... > I notict that when you #include <IdTCPClient.hpp>, i get error > that alot of variables was decleared early. on examination i noticed > that both the winsock2.h and winsock.h was include along the > IdTCPClient.hpp That is a known issue with Indy. It is more of a Microsoft problem than an Indy problem, though, because winsock.h and winsock2.h are not compatible with each other. The VCL uses winsock.h whereas Indy uses winsock2.h instead. 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