Login  
Search All Forums
Dart Home | PowerTCP Emulation for ActiveX | Custom Development Reply | PowerTCP Emulation / Telnet for ActiveX Topics | Forums   
AuthorForum: PowerTCP Emulation / Telnet for ActiveX
Topic: Auto-login and timeout issue
sjnorris

From: Shelton, CT USA
Posts: 4
Member Since: 05/27/05
posted March 23, 2008 8:43 PM

I'm trying to implement auto-connect/login using commandline parameters to specify the host, user and password. I've managed to get things working, though I'm not certain my approach is the correct one (or even safe) as I'm a novice when it comes to MFC. So my first question, is it safe or the correct approach to be calling Telnet->Connect from InitInstance?

Secondly and my more immediate concern is an issue with timeout. If the initial connect times out or if one of my Search() calls times out then the error event fires (which is expected and OK) but it also seems that some sort of exception is also being thrown as I'm also getting the following displayed by the AfxMessageBox call at the end of InitInstance: The connection had been dropped because of a network failure or because the peer system failed to respond. Also caused when Connect, Send, Receive, Fill or Close methods are used with a Timeout parameter and the operation fails to complete within the specified number of milliseconds.

My asssumption is I'm getting this exception because of my calling Telnet->Connect in InitInstance. Code is as follows:


BOOL CProTermApp::InitInstance()
{
try
{
AfxEnableControlContainer();

// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.

#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif

// Change the registry key under which our settings are stored.
SetRegistryKey(_T("ECS ProTerm"));


// Register the application's document templates. Document templates
// serve as the connection between documents, frame windows and views.

CSingleDocTemplate* pDocTemplate;
pDocTemplate = new CSingleDocTemplate(
IDR_MAINFRAME,
RUNTIME_CLASS(CProTermDoc),
RUNTIME_CLASS(CMainFrame),    // main SDI frame window
RUNTIME_CLASS(CProTermView));
AddDocTemplate(pDocTemplate);

// Parse command line switches and parameters
ECSCCommandLineInfo cmdInfo; // My CCommandlineInfo override
ParseCommandLine(cmdInfo);


// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
return FALSE;

// The one and only window has been initialized, so show and update it.
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();

// Get pointer to application main frame window
CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;

// Get the active SDI child window
CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();

// Get the active view attached to the active SDI child window
CProTermView *pView = (CProTermView *) pChild->GetActiveView();
//pView->SendMessage(UWM_APP1, 0, 0);

CString Protocol = "Telnet";
int Port = 23;
pView->Connect(cmdInfo.GetHostname(), Protocol, Port,
cmdInfo.GetUsername(),
cmdInfo.GetPassword(),
cmdInfo.GetAction());

}
catch(_com_error e)
{
AfxMessageBox(e.Description());
//return FALSE;
}
return TRUE;
}

Amit

From: Rome, NY USA
Posts: 315
Member Since: 03/15/06
posted March 25, 2008 1:49 PM

Hi Scott,

Yes, calling Connect from InitInstance is a safe approach.

The error which the application is throwing is a timeout error. This has nothing to do with InitInstance.
If Timeout is greater than 0, the Search method blocks and waits for the Token, and no error is generated if the Token arrives within the timeout period. If the timeout period is exceeded, a ptTimeout error is generated, the session is aborted, and all system resources are released.

What happens if you increase the timeout value?

What happens if you set timeout to 0 so that synchronous operations are allowed?

Regards,
Amit
sjnorris

From: Shelton, CT USA
Posts: 4
Member Since: 05/27/05
posted March 25, 2008 7:44 PM

OK, I understand the concept of using Timeout > 0 to do blocking versus Timeout = 0 for non-blocking. Increasing the timeout is not really relevant in my case because I was specifically testing to see what happens when the connection times out by purposely connecting to a bogus server and what happens when an expected prompt is not found by searching for a bogus prompt string. The reason I was testing these scenarios is I have added code to the telnet error event function to check a "login" status flag that I'm setting to monitor the login process so that I could display a more meaningful user message indicating what timed out. While I understand what that long verbose message means, it might as well be in greek as far as my customers are concerned.

What I really would like to do is suppress the message that is being displayed by the AfxMessageBox function in InitInstance when a timeout error is thrown, but only when the timeout occurs for the conditions that I'm checking, i.e. my login status flag.

What's curious is if I use the distributed example and go through the dialog to enter the connection info and specify a bogus IP address, the connection attempt times out and the only message displayed is one in the VT control: [Telnet error, Number: 10060 Description: T]. I assume the reason I don't get the timeout error thrown back to InitInstance in this case is because InitInstance has actually completed (returned TRUE) and I'm now in the connect dialog code.

As for setting the timeout = 0... Well I'm using the blocking method because it's easier to implement and I can handle my very limited Search/Send requirements directly in the View::Connect function. I'd be willing to try doing it syncronously if you could give me some idea on how to actually implement Search/Send functionality while doing syncronous communications, as frankly, I don't have a clue as to how to go about it... I assume that I would have to do this in the Telnet::Receive function. Anyway, the code below shows how I have implemented my Search/Send code to auto-login as well as what I'm trying to trap in the Telnet::Error function:

void CProTermView::Connect(CString RemoteHost, CString Protocol, int RemotePort,
  CString User, CString Password, CString Command)
{
// start countdown, trigger after one second
TimerID = SetTimer(1, 1000, NULL);
Tick = -1;
CountdownCaption.Format("Connecting to: %s", RemoteHost);
OnTimer(TimerID); // call it forcibly the first time

// Init VT ready for a new connection!
m_Vt1.SetNewLine(vtCrOnly);
m_Vt1.Clear();

pTelnet->AutoOption = TRUE;

pTelnet->Timeout = 30000;
pTelnet->Connect(_bstr_t(RemoteHost), RemotePort, _bstr_t(), 0);

if (pTelnet->State == DartTelnet::tcpConnected)
{
COleVariant Data("");
COleVariant Token("");

// Initialize AutoLoginState
AutoLoginState = 0;

// Set a 5 second timeout
pTelnet->Timeout = 5000;

// Search for login prompt and sent user login
Token = "ogin:";
pTelnet->Search(&Data, &Token);
m_Vt1.Display(&Data);
Data = User + "\n";
pTelnet->Send(&Data, 0);
AutoLoginState = 1; // Increment my login status control flag

// Search for password prompt and send password
Token = "assword:";
pTelnet->Search(&Data, &Token);
m_Vt1.Display(&Data);
Data = Password + "\n";
pTelnet->Send(&Data, 0);
AutoLoginState = 2; // Increment my login status control flag

// Search for command prompt and send command string
Token = "$";
pTelnet->Search(&Data, &Token);
m_Vt1.Display(&Data);
Data = Command + "\n";
pTelnet->Send(&Data, 0);
AutoLoginState = 3; // Increment my login status control flag

pTelnet->Timeout = 0;
}
}


void CProTermView::Telnet_Error(DartTelnet::ErrorConstants Number, BSTR Description)
{
// kill the timer if running
if (TimerID)
{
KillTimer(TimerID);
TimerID = 0;
}

// If we timed out during auto-login, display an appropriate message.
if (pTelnet->State == DartTelnet::tcpConnected && Number == DartTelnet::ptTimeout)
{
switch (AutoLoginState)
{
case 0:
MessageBox("Timed out waiting for login prompt.", NULL, MB_OK);
break;
case 1:
MessageBox("Timed out waiting for password prompt.", NULL, MB_OK);
break;
case 2:
MessageBox("Timed out waiting for command prompt.", NULL, MB_OK);
break;
default:
break;
}
}
else if (pTelnet->State != DartTelnet::tcpConnected && Number == DartTelnet::ptTimeout)
{
MessageBox("Timed out waiting for connection", NULL, MB_OK);
}

if (Number != DartTelnet::ptAbort)
{
BOOL AutoWrap = m_Vt1.GetAutoWrap();
m_Vt1.SetAutoWrap(TRUE);
CString Error;
Error.Format("[Telnet error. Number: %d Description: %s]", Number, Description);
COleVariant Data(Error);
m_Vt1.Display(&Data);
m_Vt1.SetAutoWrap(AutoWrap);
}
}


Amit

From: Rome, NY USA
Posts: 315
Member Since: 03/15/06
posted March 27, 2008 1:58 PM

Hi Scott,

If you are looking to make a blocking call, then please put it in a try.. catch block and then handle it in whatever manner you want to.

Best Regards,
Amit
Reply | PowerTCP Emulation / Telnet for ActiveX Topics | Forums   
This site is powered by PowerTCP WebServer Tool PowerTCP WebServer for ActiveX