More Information about the MFC socket
CSocket is often used with a CArchive object and a CSocketFile object to enable serialization between two socket interfaces. However, we didnít implement serialization in our applications. Instead, for TCP we used CSocket::Send(const void* lpBuf, int nBufLen, int nFlags = 0) and CSocket::Receive(void* lpBuf, int nBufLen, int nFlags = 0) (derived from CAsyncSocket) to achieve the echo effect. As for UDP, we used CSocket::SendTo() and CSocket::ReceiveFrom() (derived from CAsyncSocket), each of which is an overloaded function with two slightly different parameter lists:
1) int SendTo( const void* lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress = NULL, int nFlags = 0 );
2) int SendTo( const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags = 0 );
1) int ReceiveFrom(void* lpBuf, int nBufLen, CString& rSocketAddress, UINT& rSocketPort, int nFlags = 0 );
2) int ReceiveFrom( void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0 );
Interestingly, we observed that it was easier to use SendTo(1) than SendTo(2) in writing the UDP echo client. To make SendTo(2) work, we had to construct the Socket Address of the echo server first. Doing that may cause too much trouble for the user given that CSocket is meant to encapsulate most of the painful details of the C lanugage socket. The two ReceiveFrom() functions, however, were comparable in terms of ease of use.
We also made a few notes on the TCP threaded server: the listening socket, servSock, listens for new connections for ever. Upon acceptance of a new connection, it creates a separate socket, clntSock, for the connection, and then spawns a new thread to handle it by calling CreatThread() (view API). However, passing a CSocket object across threads does not work, as it easily causes the well-known "connection reset by peer" error. Instead, we should pass a handle to this socket to the new thread. This can be done in two lines of code, one of which appears in the context of the main thread, the other in the context of the new thread.
// Detach the newly accepted socket and save
// the SOCKET handle.
SOCKET handle = clntSockInMainThread.Detach();
// Attach the socket object to the socket handle
// in the context of this thread.
(Here is another Example showing how to do this.)
Now the handle to the client socket has been passed in, the new thread can handle the client connection by calling
Finally, a detailed view of the CSocket and CAyncSocket libraries can be found in the MSDN website. Also check out the scenario of setting up communication between a CSocket server and client.