MFCSocs.exe Avoids Two Common MFC Socket Mistakes
ID: Q185728
|
The information in this article applies to:
-
The Microsoft Foundation Classes (MFC), used with:
-
Microsoft Visual C++, 32-bit Editions, versions 5.0, 6.0
SUMMARY
The MFCSocs sample is a minimal MFC application that demonstrates how to
use the CSocket and CAsyncSocket classes to communicate in a Transmission
Control Protocol (TCP) connection. This sample is a dialog-based
application. Depending on the selection in the user interface, the
application can run either as a TCP server that listens on a certain TCP
port, or as a client that connects to a server on the same TCP port.
When running as a client, the application uses the CSocket class to
communicate with the server. When running as a server, the application uses
CAsyncSocket to listen to connection requests and communicate with the
client after the connection is established.
MORE INFORMATIONThe following files are available for download from the Microsoft
Download Center. Click the file names below to download the files:
Mfcsocs.exe
For more information about how to download files from the Microsoft
Download Center, please visit the Download Center at the following Web
address
http://www.microsoft.com/downloads/search.asp
and then click How to use the Microsoft Download Center.
This sample addresses two common mistakes that MFC socket programmers can
make:
- Issuing more than one Receive call in the OnReceive notification function.
The CSocket class implements blocking for the Receive and Send calls by looping CAsyncSocket Receive and Send calls until all the data has been received or completely sent. Therefore, the socket type of both Csocket and CAysncSocket is nonblocking. For a nonblocking socket, an FD_READ notification that the TCP stack sends to the application indicates data availability. MFC then maps the FD_READ notification to the OnReceive notification call.
In Windows Sockets, you should not make multiple recv calls within an FD_READ notification unless you are willing to disable FD_READ notifications prior to calling recv. However, CSocket and CAsyncSocket make no provision for doing so. Therefore, you should make only one Receive call per OnReceive function. Under high data transmission rate, if you make more than one Receive call in the OnReceive function, the application might lose FD_READ, have fake FD_READ, or have no FD_READ (hanging).
You can use CSocket with CArchive and CSocketFile to directly receive and send MFC CObject-derived objects. However, under high data transmission rates, you should not use CSocket with CArchive and CSocketFile within the OnReceive function because they might internally generate multiple Receive calls.
- Not issuing enough Send calls to make sure all data has been sent when using the CAsyncSocket::Send function.
When you issue an asynchronous Send call to send a buffer, there are three possible outcomes:
- The call returns the number of bytes sent, and the buffer is completely sent
- The call returns the number of bytes sent, and the buffer is partially sent
- The call returns the WSAEWOULDBLOCK error, and the buffer is not sent.
In the second case, the program should continue to issue calls to Send until either all the data has been sent or WSAEWOULDBLOCK occurs.
In the third case, when the TCP/IP stack frees more buffer space, it dispatches an FD_WRITE notification to the application that is mapped to the OnSend notification function by MFC. At this point, the program should continue to send data until either all the data has been sent or WSAEWOULDBLOCK occurs.
When you use a CSocket Receive and Send outside OnReceive and OnSend (in other words, when you use a default do-nothing OnSend and OnReceive), it is okay to use Receive and Send in a loop or use them with CArchive and CSocketFile.
Steps to Run the Sample
- Run the .exe file (exe1) and select Server. This puts the .exe
instance in server listening state.
- Run the .exe again (exe2) either on the same machine or a remote
machine. Select Client and type in the name of the machine on which exe1
is running.
- In exe2, type anything in the Send box. Click Send to make the
connection and send it. Click Yes to accept the incoming connection on
the server (exe1). Now you can send messages from either exe1 or exe2.
Note that once connected, the application does not reconnect when you
click Send.
- If either exe1 or exe2 wants to quit, type "bye" in either application and click Send. To restart communication, go to step 3.
Additional query words:
Keywords : kbfile kbnetwork kbsample kbAPI kbMFC kbSDKPlatform kbVC500 kbVC600 kbWinsock kbGrpNet
Version : winnt:5.0,6.0
Platform : winnt
Issue type : kbhowto
|