Author |
Topic |
|
KnowledgeBase
296 Posts |
Posted - 26 Feb 2002 : 15:17:16
|
Q: I can't get the MFC CCeSocket class to work. I especially have trouble with not getting the OnReceive event.
Check out this newsgroup article for a workaround to this known issue
Thanks to Larry Li of DataWatch Systems for this tip, Oct 01)
------------------ ADS Knowledge Base |
|
ctacke
877 Posts |
Posted - 13 Jan 2003 : 09:49:14
|
While the above link is no longer valid, Microsoft Knowledge Base Article 253945 addresses the issue.
In addition, it is well known that the CCeSocket MFC class has many problems and limitations. Unless you are using the class to port another MFC project to CE, it is advisable to use raw sockets or your own class implementation instead of using the CCeSocket class.
Below are a couple newsgroup posts that provide more insight. |
|
|
ctacke
877 Posts |
Posted - 13 Jan 2003 : 09:50:54
|
Newsgroup Post Posted by Dan East on 8/26/98 microsoft.public.win32.programmer.wince
I suggest you do NOT use CCeSocket unless you simply want to save development time porting another MFC app to Windows CE. If you'll notice in the documentation, it makes mention that Windows CE does not support asynchronous communication, so CCeSocket emulates the Win32 OnReceive, OnAccept, etc member functions by creating separate threads that watch for those events to occur, and then send the appropriate message. I used the OnReceive member function for a CE app. It would communicate with a server on a Windows 95 machine. However, the transfer rates were dismal (~ 2kbaud/s). I optimized every part of my code with no improvement. I finally went directly to the CAsyncSocket base class, and modified my code slightly to create a separate thread in which the blocking CAsyncSocket::Receive member is called (otherwise it would block the application's main thread). The transfer rate increased exactly 8 fold! It is still nowhere near the Windows 95 to Windows 95 transfer rate (which do use the asynchronous CSocket class), but it is much faster than a serial connection or CCeSocket. If you are not transferring large amounts of data (chat program, etc), then you won't notice the inefficiency of CCeSocket. Otherwise I would stay away from it for reasons of effeciency on an already slow platform. |
|
|
ctacke
877 Posts |
Posted - 13 Jan 2003 : 09:54:30
|
Newsgroup Post Posted by Stephen Agate on 2/15/2002 microsoft.public.win32.programmer.wince
Problem Identification:
It turns out that I had two problems (you mileage may vary depending upon the SDK version you use, as the code within WCESOCK.CPP varies quite a lot between versions. I get the feeling that Microsoft are hacking in the changes!).
First of all, I could not get a listening socket to correctly start a new data-thread during the OnAccept() call. Looking at the MFC source code and the file "WCESOCK.CPP", the DataThread() function must be started by calling BeginThread() in order to allows the reception of incoming data. However, the BeginThread() function only gets called from within the Create() function. I cannot call the Create() function on a socket to be accepted, as this causes assertions within the SOCKCORE.CPP file.
Secondly, even if you are successful in starting a new data thread, a bug exists when creating a socket via Accept() [as in a server] instead of Create() and Connect() [as in a client]. The actual problem is that the CCeSocket DataThread() thread function does not check for incoming data if the private m_bConnectedCalled member variable is not set.
Workaround #1:
[You should only need to add this workaround if you are using Windows CE 2.00]
Modify your source code to start the data-thread by creating a temporary data socket. For example add the following highlighted lines within OnAccept():
CCeSocket* pSocket=new CCeSocket;
!! static bool bFirstTimeThrough=true; !! if (bFirstTimeThrough) !! { !! CCeSocket* pSocket2=new CCeSocket; !! pSocket2->Create(); !! delete pSocket2; !! bFirstTimeThrough=false; !! }
pListeningSocket->Accept(pSocket); etc...
Luckily the code does not call EndThread() when deleting the dummy socket, so you only have to start the thread once.
Workaround #2:
This is where the fun starts. To work around the m_bConnectedCalled problem you can set the m_bConnectedCalled member variable of the CCeSocket object to TRUE after it is returned by Accept() . The problem with that is that m_bConnectedCalled is declared as private and you do not have access to it in your code. To get the required access you have to modify the WCESOCK.H SDK header file so that m_bConnectedCalled is declared as public before compiling your application. :-)
Please make a backup copy of WCESOCK.H before you modify it and take care that you do not change anything else within the header file. Just changing the declaration does not change the memory layout of the class and therefore your application will work properly with the MFC runtime DLL.
Change From:
private: fd_set m_ReadFds; fd_set m_WriteFds; static CWinThread* m_pListenThread; static CWinThread* m_pDataThread; static int m_iSocketCount; PURPOSE_E m_iPurpose; BOOL m_bQuit; BOOL m_bConnectCalled; BOOL m_bIsConnected;
To:
private: fd_set m_ReadFds; fd_set m_WriteFds; static CWinThread* m_pListenThread; static CWinThread* m_pDataThread; static int m_iSocketCount; PURPOSE_E m_iPurpose; BOOL m_bQuit; // Hack in public access!!!!!!!! public: BOOL m_bConnectCalled; BOOL m_bIsConnected; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Your code within the OnAccept() should look something like:
CServerSocket* pSocket=new CServerSocket;
// MFC Bug Fix - Must amend WCESOCK.CPP to allow access! pSocket->m_bConnectCalled=TRUE;
if (m_pListeningSocket->Accept(*pSocket)) { etc...
Whinges and Thanks
All the usual whinges apply when trying to get hold of someone "in the know" at Microsoft. I was fobbed off twice by VERY lame excuses about the problem being due to CCeSocket not supporting asynchronous socket notifications. I mean, what do they think the threads are for?
To Microsoft's credit, I received valuable help from a Microsoft Support Engineer called Manfred in the EMEA Regional Support Center, Munich (well, we paid for it as a MSDN developer). He promised that a fix would be in future versions of Windows CE MFC...
|
|
|
Susan
123 Posts |
Posted - 16 Nov 2004 : 07:34:50
|
We are looking to use sockets in one of our applications. I'm just beginning to do some research on this. The above posts are a bit dated. Is there more recent information regarding sockets and CE of which ADS is aware? |
|
|
ctacke
877 Posts |
Posted - 16 Nov 2004 : 09:20:58
|
While the posts are a bit old, MFC has not changed in a long while. It's still recommended that for all socket programming that you simply use the socket APIs and not the MFC CeSocket classes. |
|
|
|
Topic |
|
|
|