|
At which line exactly does crash occurs ?
|
|
|
|
|
This crash refered in the stack is Line 2590 and this refers to a #define
DISABLEOLEWARNINGBOXS;
// Shut off both of the OLE not ready type dialogs (error dialogs)
// The busy dialog comes up at least when the app receives some window messages and
// is in an Automation call. These two calls will shut off the dialogs.
//
#define DISABLEOLEWARNINGBOXS \
COleMessageFilter* pfilter = ::AfxOleGetMessageFilter (); \
if (NULL != pfilter) \
{ \
pfilter->EnableBusyDialog(FALSE); \
pfilter->EnableNotRespondingDialog(FALSE); \
}
With rgds,
Anil
|
|
|
|
|
Hi,
I am adding a simple client program for my MFC GUI App using(or trying to use) CAsyncSocket. I am new to socket programming in general so naturally I would have some trouble. I have no control over the server app except to start it and tell it to start sending me data. I have tried this using CSocket first but I couldn't make the receive work and/so I want to use CAsyncSocket anyway because I think it would benefit me down the road. BTW...I am using VC++ 2005. Ok...so my problem is that when using the CASyncSocket object the OnConnect() and OnReceive() notifications aren't being called as far as I can tell.(I setup my object to only give those notifications) I have overidden them in my class derived from CAsyncSocket. I know my object is connecting to the server but the weird thing is that the connect fails but then it CONNECTS ANYWAY. Then I can send a command to it and the server begins sending data packets to me(I know this because I am watching the server print these statements to my command window.) The server is DOS executable. So...
1. The connect function fails but the OnConnect() does not get called...I think it should even if there was an error...but the connect really did happen just not before the connect function returned an error!? UPDATE: Every once in a while the OnConnectFunction does get called with an error code of 0.
So, the client is connected and as far as I know the server program is working and has been tested and says that is sending data but I am not getting any OnReceive() notifications. I still have to figure out exactly what to do once I get the notifications but I would be happy to see that I am getting them for now.
2. No OnReceive() when I am pretty sure I should be getting them.
So I am just wondering if I am doing something dumb...any ideas? Thanks in advance!
Code below....
<br />
CMySocket * m_pDASsocket;<br />
<br />
m_pDASsocket = new CMySocket;<br />
m_pDASsocket->Create(0,SOCK_STREAM,FD_READ | FD_CONNECT);<br />
<br />
<br />
char startstream = 100;<br />
<br />
if(m_pDASsocket->Connect("127.0.0.1", 1101) != 0)<br />
{<br />
m_pDASsocket->Send(&startstream,1); <br />
<br />
}<br />
else<br />
{<br />
Sleep(200);<br />
m_pDASsocket->Send(&startstream,1);<br />
<br />
}<br />
<br />
<br />
<br />
char stopchar = 0;<br />
<br />
if(m_pDASsocket->Connect("127.0.0.1", 1101) != 0)<br />
{<br />
m_pDASsocket->Send(&stopchar,1); <br />
m_pDASsocket->Close();<br />
}<br />
else<br />
{<br />
Sleep(100);<br />
m_pDASsocket->Send(&stopchar,1);<br />
m_pDASsocket->Close();<br />
}<br />
<br />
<br />
<br />
void CMySocket::OnReceive(int nErrorCode)<br />
{<br />
<br />
AfxMessageBox("OnReceive");
<br />
<br />
static int i=0;<br />
<br />
i++;<br />
<br />
TCHAR buff[4096];<br />
int nRead;<br />
nRead = Receive(buff, 4096); <br />
<br />
switch (nRead)<br />
{<br />
case 0:<br />
Close();<br />
break;<br />
case SOCKET_ERROR:<br />
if (GetLastError() != WSAEWOULDBLOCK) <br />
{<br />
AfxMessageBox ("Error occurred");<br />
Close();<br />
}<br />
break;<br />
default:<br />
buff[nRead] = 0;
CString szTemp(buff);<br />
m_strRecv += szTemp;
AfxMessageBox(m_strRecv);<br />
<br />
<br />
if (szTemp.CompareNoCase("bye") == 0 ) ShutDown();<br />
}<br />
CAsyncSocket::OnReceive(nErrorCode);<br />
<br />
<br />
}<br />
<br />
<br />
Clint Smith
|
|
|
|
|
1) ALWAYS check return values from socket calls.
2) Refer to #1 above
First of all - Lots of stuff that will help immensely can be found here[^]
With that out of the way...
By using the CAsyncSocket class and specifying FD_READ | FD_CONNECT in your Create() call you are
requesting the socket be created in non-blocking mode and that you want to receive notifications
on completed connect requests and when there's data available for receiving from the socket.
When a socket is in non-blocking mode, an error is returned from almost every call involving
network operations - connect/recv/send/etc. BUT, the error is WSAEWOULDBLOCK, which just means
the operation couldn't be completed immediately and is still in progress. You don't know of
success/failure until you receive a notification. In CAsyncSocket, the notification for
FD_CONNECT gets mapped to a call to OnConnect(). When data becomes available (is sent to the
socket) then your OnReceive() will be called.
So, starting at the top of your code:
m_pDASsocket = new CMySocket;
m_pDASsocket->Create(0,SOCK_STREAM,FD_READ | FD_CONNECT);
You've created your socket - cool. As mentioned above the socket is now non-blocking.
Next you connect to your socket.
Cool. Now it's time to check error codes, something like:
if(m_pDASsocket->Connect("127.0.0.1", 1101) != 0)
{
m_pDASsocket->Send(&stopchar,1);
m_pDASsocket->Close();
}
else
{
int nErrCode = m_pDASsocket->GetLastError();
if (nErrCode == WSAEWOULDBLOCK)
{
}
else
{
m_pDASsocket->Close();
}
}
By the way, the Sleep() call, although it may have worked when connecting to the local machine,
was a really bad idea, and totally negates the purpose of asynchronous sockets. It can often take
much longer than 200ms to connect
Note that you can't call Send() until the connect completes, indicated by OnConnect() being
called with error code 0:
void CMySocket::OnConnect(int nErrorCode)
{
if (0 == nErrorCode)
{
Send(&stopchar,1);
}
else
{
}
}
Make sense?
Hopefully that will help get started with connecting properly.
I'll reply again with more about the OnReceive() code.
Mark
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Hey Mark...thanks so much for your help. What your saying is making alot of sense. It seems like OnConnect() notification is working now. I haven't had a chance to try to receive anything but I wanted to thank you for your help. I will keep posting as I progress along.
Clint
csmithmaui
"Turn My Headphones Up!"
|
|
|
|
|
You're welcome.
C++ no ka oi
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Mark Salsbery wrote: You're welcome.
C++ no ka oi
Hey Mark...have you been to Maui before?
csmithmaui
"Turn My Headphones Up!"
|
|
|
|
|
Sadly, not yet.
My dad lives in Lahaina.
Maybe this year I'll finally get over there!
Mark
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Oh cool...yeah...it's great over here. Hope you get to come out!
Clint
csmithmaui
"Turn My Headphones Up!"
|
|
|
|
|
I want to! I'm a long time surfer. I gave up the corporate life to do my own project so I
could hopefully have time to travel and surf. I also stopped surfing so I could focus. That was
5 years ago LOL. I'm almost done thank goodness!
I have to get some place tropical. California definitely is not
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
All the stuff in my previous post applies to the "client" side of the connection.
You never mention a listening socket or using Accept() to accept a connection on the server.
Are you calling connect from both ends (if so, this won't work)?
Mark
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
Mark...I am not calling from both ends as far as I know. The server is "listening" on the port. This is the only code that I have from the server. I didn't write it.
#define CMDSERVERPORT 1101
#define CMDSERVER_MAX_CONNECTIONS 4
struct sockaddr_in sockaddrinServer;
sockaddrinServer.sin_family = AF_INET;
sockaddrinServer.sin_port = htons(CMDSERVERPORT);
sockaddrinServer.sin_addr.s_addr = htonl(INADDR_ANY);
WSAStartup(MAKEWORD(1, 1), &wsadataSocket)
g_socketServerCommand = socket(AF_INET, SOCK_STREAM, 0))
bind(g_socketServerCommand, (struct sockaddr *)&sockaddrinServer, sizeof(struct sockaddr_in)))
listen(g_socketServerCommand, CMDSERVER_MAX_CONNECTIONS)
csmithmaui
"Turn My Headphones Up!"
|
|
|
|
|
Ok, thanks. I was looking at your posted code again and realized you had two sets of connect
code there
I hope the author of the server code understands that the second param to listen() just sets the
number of possible pending connections (default is 5), not the total max connections possible.
Setting it to 4 seems kind of....unnecessary
Mark
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
About the receive code...
From what I see above you are connecting, sending some data, and closing the socket. In that
case you are never going to get a FD_READ notification to trigger the OnReceive() call unless the
server happens to send some data fast enough at connect time. Unlikely.
There's two issues I see with your OnReceive handler, assuming it does get called before the
socket is closed:
1) You've maybe assumed you will receive the entire string in one call to Receive(). This is
not always the case. A successful recv() on a socket will return 1 or more bytes, up to the
number of bytes requested. If you receive one byte and you are expecting 10 bytes then you'll
need to handle that.
2) You are requesting 4096 bytes to receive. This is only ok (in your sample code) if you have a
communication protocol where the other end sends 4096 byte "packets" or you only plan on receiving
once before closing the socket. Generally with TCP you should know how many bytes to expect and
only receive that many, unless you cache received data and parse it later (or maybe on another
thread).
Mark
"Great job, team. Head back to base for debriefing and cocktails."
(Spottswoode "Team America")
|
|
|
|
|
I receive the following error when doing the build:
Cannot open include file: 'Resource.h': No such file or directory
The resource.h file is physically located within the proper directory with the other source files. This just started happening. I was able to build with no problems prioor to this message. This is VC++ 6.0
Thanks
John P.
|
|
|
|
|
You've probably changed your include path, either in the project settings, in the environment settings, or by changing to a different project configuration that wasn't updated when a change was made previously.
The paths in the 'include path' option in project settings are relative to the location of the project file.
|
|
|
|
|
Thank you for that info!
John P.
|
|
|
|
|
whether the Resource file is included in Project.
VIBIN
"Fool's run away,where angle's fear to tread"
|
|
|
|
|
I tried to "re-include" it, and it tells me that it's already there. Doesn't make logical sense to me.
John P.
|
|
|
|
|
Try this.
1)Take a copy of ur project..
2)In that copy u delete the resourc file from the project. Not from the folder.
3)Now include the resource file again.(Project - add to project - Files )
Check out whether the above is working...
VIBIN
"Fool's run away,where angle's fear to tread"
|
|
|
|
|
Thanks. I'll give that a try.
John P.
|
|
|
|
|
|
Or I can just do the following:
HWND hConsoleHandle = FindWindow(NULL, (LPCTSTR)"Window Name");
ShowWindow(hConsoleHandle, SW_SHOWMAXIMIZED);
Regards,
The only programmers that are better than C programmers are those who code in 1's and 0's.....
Programm3r My Blog: ^_^
|
|
|
|
|
Programm3r wrote: WINDOWPLACEMENT *lpwndpl; lpwndpl->length = sizeof(lpwndpl); lpwndpl->showCmd = SW_SHOWMAXIMIZED; GetWindowPlacement(hConsoleHandle,lpwndpl);
Yuo've never allocated the memory that contains the WINDOWPLACEMENT variable, Plus, using sizeof on a pointer returns the size of the pointer, not the structure. Change this to
WINDOWPLACEMENT wndpl;
wndpl.length = sizeof(wndpl);
wndpl.showCmd = SW_SHOWMAXIMIZED;
GetWindowPlacement(hConsoleHandle,&wndpl);
Judy
|
|
|
|
|
I thought this was going to be an easy one since the MSDN documentation seems to indicate that there is a CWinApp::HtmlHelp() member function. I have a feeling the MSDN I am using is meant for use with a newer version of Visual Studio 6. My CWinApp header does not have such a member function.
Is there any other way to use Html Help in a VC6 project? I don't need to build the chm's - I just want to be able to call them (replace CWinApp::WinHelp()).
Thanks,
Dave
|
|
|
|