Re: Terminating Accept
On Mar 22, 9:33 pm, Joseph M. Newcomer <newco...@flounder.com> wrote:
See below...
On Mon, 22 Mar 2010 07:28:21 -0700 (PDT), dushkin <talt...@gmail.com> wro=
te:
Hi All.
Recently I posted a question (http://groups.google.com/group/
microsoft.public.vc.mfc/browse_thread/thread/6ec9bd3dc80c408e#) about
a problem regarding closing an app using a system tray icon menu.
What I didn't know till now is that the problem was a
CAsyncSocket::Accept() function that was waiting for a connection and
****
If you got an OnAccept() notification without error, then the Accept() sh=
ould be
immediate, becuase the connection has actually been established at the lo=
wer level of the
protocol statck. You should not be calling Accept() except in the OnAc=
cept() handler.
****>probably blocked some messaging or something. Therfore the applicati=
on
never exited. When I removed the accept function part - the closing of
the app via the system tray menu succeeded.
So I tried to move the listen/accept while loop into a separate
thread. I thought that this way the accept won't interfere in closing
the app. But then, when I tried to stop the "accept" with some closing
functions as you will see in the code, in order to allow the "Exit"
app in the menu to work, the CAsyncSocket::Close() crashed and the
accept didn't stop working anyway.
Listen() is never part of the loop; Listen() merely makes the socket bind=
ing publicly
accessible, so the loop is
Bind()
Listen();
while(true)
{
Accept(...);
}
I have no idea what the nonsensical word "crash" means, since you failed =
to explain the
phenomenon you observed. Note that for CAsyncSocket, you would NEVER w=
rite the above
loop, it makes no sens whatsoever! Instead, you would handle the Accep=
t() in your
OnAccept() handler., so the fact that you have written a loop means you d=
on't understand
how CAsyncSocket actually works, and therefore your code is erroneous. =
Fix your code
first.
****
I read somewhere that you wouldn't like to put this loop in a thread.
****
No, it is erroneous code.
****
My question is how to deal with this problem.
Actually, I think I need to somehow stop the "Accept" operation and
thus allow the system tray messages to work.
****
Did you call Shutdown() to shut down the socket?
*****
How do I do it?
Following is the class code. I removed some of the AboutBox code and
some other irrelevant code. I use a class for the system tray
functionality.
Thanks.
------------------------------------------------------------------------=
--
// PAADlg.cpp : implementation file
//
#include "stdafx.h"
#include "PAA.h"
#include "PAADlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
bool g_stop = false;
CEvent gEvent;
UINT RunListener(LPVOID lpParam);
// CPAADlg dialog
CPAADlg::CPAADlg(CWnd* pParent /*=NULL*/)
: CDialog(CPAADlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_DefaultMenuItemByPos = TRUE;
m_pParentWnd = pParent;
}
CPAADlg::~CPAADlg(){
g_stop = true;
//Trying to close Accept operation when exiting app
m_ListeningSocket.CancelBlockingCall();
m_ListeningSocket.ShutDown();
m_ListeningSocket.Close();
m_ConnectedSocket.Close();
WaitForSingleObject(gEvent.m_hObject, INFINITE);
****
There is NOTHING CORRECT or even POSSIBLY CORRECT about this code! The=
WFSO in a
constructor means that this will hang until the event is set, which means=
you get no UI at
all. NEVER write code like this, ever, under any imginable circumstanc=
es
If you want to close the log file when the thread terminates, have the th=
read PostMessage
a user-defined message, which you handle in your dialog, and close the lo=
g file there!
This is absolutely HORRIBLE code!
*****
m_autoLog.Close();
}
void CPAADlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
***
Nothing happens. You never get here. The constructor hangs
****
BEGIN_MESSAGE_MAP(CPAADlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_ICON_NOTIFY, OnTrayNotification)
END_MESSAGE_MAP()
****
YOu will get no notifications of any sort until that event gets set. T=
herefore, this code
won't handle anything. It can never be invoked, because the thread has=
blocked during the
constructor!
*****
// CPAADlg message handlers
BOOL CPAADlg::OnInitDialog()
{
***
You will never get here because the code hangs in the constructor
****
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUT=
BOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATO=
R);
pSysMenu->AppendMenu(MF_STRING, =
IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this
automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set b=
ig icon
SetIcon(m_hIcon, FALSE); // Set s=
mall icon
//HICON hIcon = ::LoadIcon(NULL, IDI_ASTERISK);
HICON hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
if (!m_TrayIcon.Create(NULL, WM_ICON_NOTIFY, "Hello", hIcon,
IDR_POPUP_MENU))
return -1;
if(! CreateLogFile())
return FALSE;
gEvent.ResetEvent();
****
The use of events scares me. You don't need any, and if you have them,=
your code is
probably wrong. Unless you made the deep mistake of believing the horr=
ible KB article on
multithreaded sockets, in which case, your code will be complete trash an=
d can only be
rewritten completely to salvage it (see my essay on my MVP TIps site on m=
ultithreaded
asynschronous sockets. which shows why the Microsoft article is comple=
te rubbish, having
been written by someone who did not understand sockets, or threading, or =
synchronization).
****
CWinThread* pThread = AfxBeginThread(RunListener ,this);
if(!pThread)
AfxMessageBox("Thread Error!");
****
YOu might want to look at my ToString function, which takes a formatting =
string and
arguments and returns a CString, which allows you to say something meanin=
gful here, such
as WHY there is a failure to create the thread!
*****
return TRUE; // return TRUE unless you set the focus to a =
control
}
void CPAADlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code
below
// to draw the icon. For MFC applications using the document/view
model,
// this is automatically done for you by the framework.
****
YOu might want to move this function so it doesn't have the wrong comment=
above it!
****
BOOL CPAADlg::CreateLogFile()
{
CFileException e;
if(!m_autoLog.Open("c:\\AutoPaAgn.log", CFile::modeCreate|
CFile::modeNoTruncate|CFile::modeWrite, &e)){
CString s;
s.Format("%d", e.m_cause);
AfxMessageBox(s);
return FALSE;
}
return TRUE;
}
void CPAADlg::WriteToFile(CString a_sLine)
{
CTime tm = CTime::GetCurrentTime();
m_autoLog.WriteString(tm.Format("%H.%M.%S : ") + a_sLine);
****
Why is this not in a try...catch block? It can throw an exception. =
And why do you
presume time formatting is %H.%M.%S, which is cultural and should change =
based on locale?
****
}
LRESULT CPAADlg::OnTrayNotification(WPARAM wParam, LPARAM lParam)
{
//Return quickly if its not for this tray icon
if (wParam != m_tnd.uID)
return 0L;
CMenu menu, *pSubMenu;
// Clicking with right button brings up a context menu
if (LOWORD(lParam) == WM_RBUTTONUP)
{
if (!menu.LoadMenu(m_tnd.uID))
return 0;
pSubMenu = menu.GetSubMenu(0);
if (!pSubMenu)
return 0;
// Display and track the popup menu
CPoint pos;
GetCursorPos(&pos);
SetForegroundWindow();
pSubMenu->TrackPopupMenu(TPM_LEFTALIGN, pos.x, p=
os.y, this, NULL);
PostMessage(WM_NULL, 0, 0);
****
And the purpose of posting WM_NULL is what?
****
menu.DestroyMenu();
}
else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
{
// double click received, the default action is =
to execute default
menu item
SetForegroundWindow();
UINT uItem;
if (m_DefaultMenuItemByPos)
***
This code makes me nervous. Where is m_defaultMenuItemID set? I can=
not find where the
subroutine below is called. At this point, I'd search for the default =
menu item as set in
the menu and not trust any global variable to tell me what it was.
****
{
if (!menu.LoadMenu(m_tnd.uID))
return 0;
pSubMenu = menu.GetSubMenu(0);
if (!pSubMenu)
return 0;
uItem = pSubMenu->GetMenuItemI=
D(m_DefaultMenuItemID);
menu.DestroyMenu();
}
else
uItem = m_DefaultMenuItemID;
PostMessage(WM_COMMAND, uItem, 0);
}
return 1;
}
BOOL CPAADlg::SetMenuDefaultItem(UINT uItem, BOOL bByPos)
{
if ((m_DefaultMenuItemID == uItem) && (m_DefaultMenuItemByPo=
s ==
bByPos))
return TRUE;
m_DefaultMenuItemID = uItem;
m_DefaultMenuItemByPos = bByPos;
CMenu menu, *pSubMenu;
if (!menu.LoadMenu(m_tnd.uID))
return FALSE;
pSubMenu = menu.GetSubMenu(0);
if (!pSubMenu)
return FALSE;
::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID,
m_DefaultMenuItemByPos);
return TRUE;
}
void CPAADlg::GetMenuDefaultItem(UINT& uItem, BOOL& bByPos)
{
uItem = m_DefaultMenuItemID;
bByPos = m_DefaultMenuItemByPos;
}
UINT RunListener(LPVOID lpParam)
****
WHy is this a global function? If you don't want to make it a static c=
lass member, it
should at least be a static name within this compilation unit. But it =
is sloppy to use a
global function for a thread function; you should always use a static met=
hod of your class
e.g.,
class CPAADlg : public CDIalog {
...
read more =BB
Joseph,
Your answers are the best and I learn much of them. I just wish your
attitude were a little more tolerant...
Anyhow, I started to implement the OnAccept, OnSend, etc.
I tried to follow the example on chapter 24 in "MFC Programming with
Visual C++ 6 Unleashed" as much as possible. I built a client app and
a server app.
The server seems to get up and wait for a request on accept.
But for some reason the client fails to connect. It returns error
10035. Now, I read in some places what you and other wrote about it -
that it is a natural behavior of an asynchronous socket. But I didn't
understand how to deal with it and why does it happen? How can we
avoid it - if at all?
Also I can tell that the OnSend is called and the Onconnect not. I
understand the latter (because connect failed) but don;t understand
the first one.
Another issue I need to know how to implement is - after the
agent(server) gets the request and does what he do with it - it needs
to send an ack back to the client.
can you explain me how?
I will post here the code, but I will appreciate if you will remember
that I am relatively a newbie and I hope your answers will be tolerant
but professional as always.
I still haven't implemented all the recommendations you gave me
before. Their time will sure come.
(also sorry for my not perfect English - it is not my mother tongue)
---------------------------------------------------------------------------=
-----------------------------------
Socket - h
---------------------------------------------------------------------------=
-----------------------------------
class CPaaSock : public CAsyncSocket
{
public:
CPaaSock();
virtual ~CPaaSock();
void SetParent(CDialog *pWnd)
{
// Set the member pointer
m_pWnd = pWnd;
}
private:
CDialog* m_pWnd;
public:
virtual void OnAccept(int nErrorCode);
virtual void OnClose(int nErrorCode);
virtual void OnConnect(int nErrorCode);
virtual void OnReceive(int nErrorCode);
virtual void OnSend(int nErrorCode);
};
---------------------------------------------------------------------------=
-----------------------------------
Socket - cpp
---------------------------------------------------------------------------=
-----------------------------------
// CPaaSock member functions
void CPaaSock::OnConnect(int nErrorCode)
{
// Were there any errors?
if (nErrorCode == 0)
// No, call the dialog's OnAccept function
((CPAMDlg*)m_pWnd)->OnAccept();
}
void CPaaSock::OnAccept(int nErrorCode)
{
// Were there any errors?
if (nErrorCode == 0)
// No, call the dialog's OnAccept function
((CPAMDlg*)m_pWnd)->OnAccept();
}
void CPaaSock::OnReceive(int nErrorCode)
{
// Were there any errors?
if (nErrorCode == 0)
// No, call the dialog's OnAccept function
((CPAMDlg*)m_pWnd)->OnReceive();
}
void CPaaSock::OnSend(int nErrorCode)
{
// Were there any errors?
if (nErrorCode == 0)
// No, call the dialog's OnAccept function
((CPAMDlg*)m_pWnd)->OnSend();
}
void CPaaSock::OnClose(int nErrorCode)
{
// Were there any errors?
if (nErrorCode == 0)
// No, call the dialog's OnAccept function
((CPAMDlg*)m_pWnd)->OnClose();
}
---------------------------------------------------------------------------=
-----------------------------------
Server - h
---------------------------------------------------------------------------=
-----------------------------------
// PAADlg.h : header file
//
#pragma once
#include "SystemTray.h"
#include "PaaSock.h"
#define WM_ICON_NOTIFY WM_APP+10
// CPAADlg dialog
class CPAADlg : public CDialog
{
// Construction
public:
CPAADlg(CWnd* pParent = NULL); // standard constructor
virtual ~CPAADlg();
// Change menu default item
void GetMenuDefaultItem(UINT& uItem, BOOL& bByPos);
BOOL SetMenuDefaultItem(UINT uItem, BOOL bByPos);
CString PeerAddress() const { return m_sPeerAddress; }
void SetPeerAddress(CString val) { m_sPeerAddress = val; }
UINT& PeerPort() { return m_uPeerPort; }
void SetPeerPort(UINT val) { m_uPeerPort = val; }
void SendCompletionAck(void);
bool RunScript(char a_sScriptName[]);
void WriteToFile(CString line);
CPaaSock m_sListenSocket; //used for listening for connection
requests
CPaaSock m_sConnectSocket; //used for sending messages back and forth
void OnAccept();
void OnConnect();
void OnReceive();
void OnSend();
void OnClose();
// Default handler for tray notification message
virtual LRESULT OnTrayNotification(WPARAM uID, LPARAM lEvent);
// Dialog Data
enum { IDD = IDD_PAA_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
private:
CString m_sPeerAddress;
UINT m_uPeerPort;
BOOL CreateLogFile();
CStdioFile m_autoLog;
CWnd* m_pParentWnd;
CSystemTray m_TrayIcon;
NOTIFYICONDATA m_tnd;
UINT m_DefaultMenuItemID;
BOOL m_DefaultMenuItemByPos;
BOOL m_bVisible;
void StartListen();
public:
afx_msg void OnWindowPosChanging(WINDOWPOS* lpwndpos);
};
---------------------------------------------------------------------------=
-----------------------------------
Server - cpp
---------------------------------------------------------------------------=
-----------------------------------
// PAADlg.cpp : implementation file
//
#include "stdafx.h"
#include "PAA.h"
#include "PaaSock.h"
#include "PAADlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
const CString sLibrary("c:\\Automation Scripts\\");
static const UINT iListenPort = 4000;
// CPAADlg dialog
CPAADlg::CPAADlg(CWnd* pParent /*=NULL*/)
: CDialog(CPAADlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_DefaultMenuItemByPos = TRUE;
m_pParentWnd = pParent;
m_bVisible = FALSE;
}
CPAADlg::~CPAADlg(){
m_autoLog.Close();
}
void CPAADlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CPAADlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_ICON_NOTIFY, OnTrayNotification)
ON_WM_WINDOWPOSCHANGING()
END_MESSAGE_MAP()
// CPAADlg message handlers
BOOL CPAADlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this
automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
//HICON hIcon = ::LoadIcon(NULL, IDI_ASTERISK);
HICON hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
if (!m_TrayIcon.Create(NULL, WM_ICON_NOTIFY, "PA Automation Agent",
hIcon, IDR_POPUP_MENU))
return -1;
if(! CreateLogFile())
return FALSE;
m_sListenSocket.SetParent(this);
m_sConnectSocket.SetParent(this);
StartListen();
return TRUE; // return TRUE unless you set the focus to a control
}
BOOL CPAADlg::CreateLogFile()
{
CFileException e;
if(!m_autoLog.Open("c:\\AutoPaAgn.log", CFile::modeCreate|
CFile::modeNoTruncate|CFile::modeWrite, &e)){
CString s;
s.Format("%d", e.m_cause);
AfxMessageBox(s);
return FALSE;
}
return TRUE;
}
void CPAADlg::WriteToFile(CString a_sLine)
{
CTime tm = CTime::GetCurrentTime();
m_autoLog.WriteString(tm.Format("%H.%M.%S : ") + a_sLine);
}
LRESULT CPAADlg::OnTrayNotification(WPARAM wParam, LPARAM lParam)
{
//Return quickly if its not for this tray icon
if (wParam != m_tnd.uID)
return 0L;
CMenu menu, *pSubMenu;
// Clicking with right button brings up a context menu
if (LOWORD(lParam) == WM_RBUTTONUP)
{
if (!menu.LoadMenu(m_tnd.uID))
return 0;
pSubMenu = menu.GetSubMenu(0);
if (!pSubMenu)
return 0;
// Display and track the popup menu
CPoint pos;
GetCursorPos(&pos);
SetForegroundWindow();
pSubMenu->TrackPopupMenu(TPM_LEFTALIGN, pos.x, pos.y, this, NULL);
PostMessage(WM_NULL, 0, 0);
menu.DestroyMenu();
}
else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
{
// double click received, the default action is to execute default
menu item
SetForegroundWindow();
UINT uItem;
if (m_DefaultMenuItemByPos)
{
if (!menu.LoadMenu(m_tnd.uID))
return 0;
pSubMenu = menu.GetSubMenu(0);
if (!pSubMenu)
return 0;
uItem = pSubMenu->GetMenuItemID(m_DefaultMenuItemID);
menu.DestroyMenu();
}
else
uItem = m_DefaultMenuItemID;
PostMessage(WM_COMMAND, uItem, 0);
}
return 1;
}
BOOL CPAADlg::SetMenuDefaultItem(UINT uItem, BOOL bByPos)
{
if ((m_DefaultMenuItemID == uItem) && (m_DefaultMenuItemByPos ==
bByPos))
return TRUE;
m_DefaultMenuItemID = uItem;
m_DefaultMenuItemByPos = bByPos;
CMenu menu, *pSubMenu;
if (!menu.LoadMenu(m_tnd.uID))
return FALSE;
pSubMenu = menu.GetSubMenu(0);
if (!pSubMenu)
return FALSE;
::SetMenuDefaultItem(pSubMenu->m_hMenu, m_DefaultMenuItemID,
m_DefaultMenuItemByPos);
return TRUE;
}
void CPAADlg::GetMenuDefaultItem(UINT& uItem, BOOL& bByPos)
{
uItem = m_DefaultMenuItemID;
bByPos = m_DefaultMenuItemByPos;
}
bool CPAADlg::RunScript(char a_sScriptName[])
{
CString s("Agent - RunScript ");
WriteToFile( s + a_sScriptName + "\n");
CString sScriptFullPath = sLibrary + a_sScriptName + ".au3";
CString cmdLine;
cmdLine.Format("\"c:\\Program Files\\AutoIt3\\AutoIt3.exe\" \"%s\"",
sScriptFullPath);
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof STARTUPINFO;
PROCESS_INFORMATION pi;
BOOL res = CreateProcess(NULL,
cmdLine.GetBuffer(),
NULL,
NULL,
NULL,
NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi);
if (TRUE == res)
{
WriteToFile("Agent - RunScript - Process created\n");
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
}
return false;
}
void CPAADlg::SendCompletionAck(void)
{
while (1)
{
char Buf[10];
HKEY hKey;
DWORD type = REG_SZ;
long lRetCode;
DWORD size = 10;
lRetCode = RegOpenKeyEx ( HKEY_LOCAL_MACHINE, "SOFTWARE\\AutoIt3Att\
\Scripts\\Flags", 0,KEY_READ,&hKey);
if (lRetCode == ERROR_SUCCESS){
WriteToFile("Agent - SendCompletionAck - Opened Complete Flag
registry Key\n");
lRetCode=::RegQueryValueEx(hKey,"Completed",NULL,NULL,(unsigned
char *)Buf,&size);
if(lRetCode == ERROR_SUCCESS){
Buf[1]=0;//the flag is 1 byte long: "1" or "0"
if (strcmp(Buf, "1") == 0)
{
WriteToFile("Agent - SendCompletionAck - Complete Flag registry
Key is 1\n");
CSocket sock;
if (sock.Create())//on any port
{
WriteToFile("Agent - SendCompletionAck Socket Created\n");
CString s;
s.Format("Agent - Peer IP is %s\n", m_sPeerAddress);
WriteToFile(s);
if (sock.Connect(m_sPeerAddress, 6666))
{
WriteToFile("Agent - SendCompletionAck Socket Connected\n");
int iAmtSent;
char buf[] ="1";
iAmtSent = sock.Send(buf, 1);
WriteToFile("Agent - Sent Completion Ack\n");
return;
}
else
{
CString s;
s.Format("Agent - SendCompletionAck Socket Connect Error: %d
\n", GetLastError());
WriteToFile(s);
}
}
else
{
CString s;
s.Format("Agent - SendCompletionAck Socket Create Error: %d\n",
GetLastError());
WriteToFile(s);
}
}else{
WriteToFile("Agent - SendCompletionAck - Complete Flag registry
Key is 0\n");
}
}
else
{
WriteToFile("Agent - SendCompletionAck - Failed to read Complete
Flag registry Key\n");
}
RegCloseKey(hKey);
}
else
{
WriteToFile("Agent - SendCompletionAck - Failed to open Complete
Flag registry Key\n");
}
Sleep(1000);
}//end while
}
void CPAADlg::StartListen(){
// Create a socket bound to the port specified
m_sListenSocket.Create(iListenPort);
WriteToFile("Agent - Socket Created\n");
// Listen for connection requests
m_sListenSocket.Listen();
WriteToFile("Agent - Ready for next message\n");
}
void CPAADlg::OnAccept()
{
// Accept the connection request
m_sListenSocket.Accept(m_sConnectSocket);
WriteToFile("Agent - Message Accepted\n");
}
void CPAADlg::OnConnect()
{
}
void CPAADlg::OnReceive()
{
char *pBuf = new char[1025];
int iBufSize = 1024;
int iRcvd;
CString strRecvd;
// Receive the message
iRcvd = m_sConnectSocket.Receive(pBuf, iBufSize);
WriteToFile("Agent - Message Received\n");
if (iRcvd == SOCKET_ERROR)
{
CString s;
s.Format("Agent - Receive Error: %d\n", GetLastError());
WriteToFile(s);
}
else
{
m_sConnectSocket.GetPeerName(PeerAddress(), PeerPort());
pBuf[iRcvd] = NULL;
WriteToFile("Agent - Handle Message\n");
RegDeleteKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\AutoIt3Att\\Scripts\
\Flags");
if(RunScript(pBuf))
SendCompletionAck();
}
}
void CPAADlg::OnSend()
{
}
void CPAADlg::OnClose()
{
// Close the connected socket
m_sConnectSocket.Close();
}
//Keep dialog hidden!
void CPAADlg::OnWindowPosChanging(WINDOWPOS* lpwndpos)
{
if(!m_bVisible)
lpwndpos->flags &= ~SWP_SHOWWINDOW;
CDialog::OnWindowPosChanging(lpwndpos);
}
---------------------------------------------------------------------------=
-----------------------------------
Client - h
---------------------------------------------------------------------------=
-----------------------------------
// PAMDlg.h : header file
//
#pragma once
#include "PaaSock.h"
// CPAMDlg dialog
class CPAMDlg : public CDialog
{
// Construction
public:
CPAMDlg(CWnd* pParent = NULL); // standard constructor
CPaaSock m_sConnectSocket; //used for sending messages back and forth
void OnAccept();
void OnConnect();
void OnReceive();
void OnSend();
void OnClose();
// Dialog Data
enum { IDD = IDD_PAM_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
BOOL CreateLogFile();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
public:
void Run();
void SendScriptRequest(const CString& a_sAddress, char
a_sScriptName[], bool a_bWaitForCompleteAck = true);
private:
void WaitForCompletionAck(void);
CStdioFile m_autoLog;
char m_sScriptName[255];
void WriteToLog(const CString& line);
public:
virtual BOOL DestroyWindow();
};
---------------------------------------------------------------------------=
-----------------------------------
Client - cpp
---------------------------------------------------------------------------=
-----------------------------------
// PAMDlg.cpp : implementation file
//
#include "stdafx.h"
#include "PAM.h"
#include "PaaSock.h"
#include "PAMDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
static const UINT iServerPort = 4000;
// CPAMDlg dialog
CPAMDlg::CPAMDlg(CWnd* pParent /*=NULL*/)
: CDialog(CPAMDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CPAMDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CPAMDlg, CDialog)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
// ON_WM_CLOSE()
END_MESSAGE_MAP()
// CPAMDlg message handlers
BOOL CPAMDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this
automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
if(! CreateLogFile())
return FALSE;
m_sConnectSocket.SetParent(this);
Run();
return TRUE; // return TRUE unless you set the focus to a control
}
void CPAMDlg::Run()
{
WriteToLog("Manager - Button Clicked\n");
SendScriptRequest(_T("localhost"), "LoginToACC");
}
void CPAMDlg::SendScriptRequest(const CString& a_sAddress, char
a_sScriptName[], bool a_bWaitForCompleteAck)
{
Sleep(1000);
strcpy_s(m_sScriptName, a_sScriptName);
m_sConnectSocket.Create();//on any port
WriteToLog("\n");
WriteToLog("Manager - Socket Created\n");
m_sConnectSocket.Connect(a_sAddress, iServerPort);
}
BOOL CPAMDlg::DestroyWindow()
{
m_autoLog.Close();
return CDialog::DestroyWindow();
}
BOOL CPAMDlg::CreateLogFile()
{
CFileException e;
if(!m_autoLog.Open("c:\\AutoPaMan.log", CFile::modeCreate|
CFile::modeNoTruncate|CFile::modeWrite, &e)){
CString s;
s.Format("%d", e.m_cause);
AfxMessageBox(s);
return FALSE;
}
return TRUE;
}
void CPAMDlg::WriteToLog(const CString& line)
{
CTime tm = CTime::GetCurrentTime();
m_autoLog.WriteString(tm.Format("%H.%M.%S : ") + line);
}
void CPAMDlg::OnConnect()
{
WriteToLog("Manager - Socket Connected\n");
int iAmtSent;
CString s("Manager - Going to send ");
WriteToLog(s + m_sScriptName + " Request\n");
iAmtSent = m_sConnectSocket.Send(m_sScriptName,
strlen(m_sScriptName));
}
void CPAMDlg::OnClose()
{
// Close the connected socket
m_sConnectSocket.Close();
}
void CPAMDlg::OnAccept()
{
}
void CPAMDlg::OnSend()
{
WriteToLog("Manager - Message Sent !\n");
}
void CPAMDlg::OnReceive()
{
}