The CAsyncSocket class is a low-level encapsulation class for WinSock APIs in the MFC of VC ++. It is applicable to the use of WinSock API flexibility and the convenience of message event mechanism in MFC, but CAsyncSocket does not support IPX/SPX protocol. I recently developed a program for transmitting SPX packets based on the IPX/SPX protocol, which reloads the Create, Bind, Connect, Socket, and Accept functions of the CAsyncSocket class, the CAsyncSocket class successfully supports the IPX/SPX protocol. The following describes the specific implementation.
Let's take a look.AsyncSocket: Create () function definition
BOOL Create (UINT nSocketPort = 0, int nSocketType = SOCK_STREAM,
Long lEvent = FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
LPCTSTR lpszSocketAddress = NULL );
The first parameter is the socket port, and the second parameter is the socket type. The default parameter is the streaming socket. The third parameter is the event generated for the socket, and the fourth parameter is the socket address. The default parameter isNULL. The following is the implementation of this function:
BOOL CAsyncSocket: Create (UINT nSocketPort, int nSocketType,
Long lEvent, LPCTSTR lpszSocketAddress)
{
If (Socket (nSocketType, lEvent ))
{
If (Bind (nSocketPort, lpszSocketAddress ))
Return TRUE;
Int nResult = GetLastError ();
Close ();
WSASetLastError (nResult );
}
Return FALSE;
}
Please take a closer look at the above Code, in factThe Create FUNCTION calls two functions: Socket and Bind. from the code above, we still cannot see that the CAsyncSocket class handles TCP/IP and IPX/SPX protocols differently.
So let's take a look.Socket Functions
BOOL Socket (int nSocketType = SOCK_STREAM, long lEvent =
FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
Int nProtocolType = 0, int nAddressFormat = PF_INET );
NextSocket function implementation
BOOL CAsyncSocket: Socket (int nSocketType, long lEvent,
Int nProtocolType, int nAddressFormat)
{
ASSERT (m_hSocket = INVALID_SOCKET );
M_hSocket = socket (nAddressFormat, nSocketType, nProtocolType );
If (m_hSocket! = INVALID_SOCKET)
{
CAsyncSocket: AttachHandle (m_hSocket, this, FALSE );
Return AsyncSelect (lEvent );
}
Return FALSE;
}
I can see it clearly.
M_hSocket = socket (nAddressFormat, nSocketType, nProtocolType );
I want to be familiarWinSock API programmers will know that, in fact, this is to create a new socket in WinSock API. The first parameter nAddressFormat is the protocol family used by the socket. In winsock2.h, We can find
# Define PF_INET AF_INET
# Define PF_IPX AF_IPX
These two definitions,PF_INET indicates that the newly created socket uses the TCP/IP protocol, while PF_IPX uses the IPX/SPX protocol.
The second parameterNSocketType is a streaming socket by default, and the third parameter nProtocolType is the specified protocol type.
InThis definition is available in winsock2.h.
# Define IPPROTO_IP 0
Default parameters0 is the IP package.
Call with default parametersIn the case of the Create function, that is
CAsyncSocket: Create ();
ArrivedCAsyncSocket: Socket function
M_hSocket = socket (nAddressFormat, nSocketType, nProtocolType );
This sentence becomes
M_hSocket = socket (AF_INET, SOCK_STREAM, IPROTO_IP );
I think everyone knows it now.CAsyncSocket class does not support IPX/SPX protocol because it creates a TCP/IP-based stream or PACKET socket by default. To enable the CAsyncSocket class to support IPX/SPX, we need to modify it here first.
InIn the WinSock API, create a streaming socket that transmits the SPX package based on IPX/SPX protocol.
SOCKET sdServer;
SOCKADDR_IPX IPXAddr;
Int addrlen = sizeof (SOCKADDR_IPX );
SdServer = socket (AF_IPX, SOCK_STREAM, NSPROTO_SPX );
ZeroMemory (& IPXAddr, sizeof (SOCKADDR_IPX ));
IPXAddr. safamily = AF_IPX;
IPXAddr. sa_socket = hotns (9000 );
Bind (sdServer, (PSOCKADDR) & IPXAddr, sizeof (SOCKADDR_IPX );
The IPX application binds the local address and socket through bind, and the binding port is 9000. We do not need to specify the network number and Node Address in SOCKADDR_IPX. The bind function will automatically use the system's first available IPX network interface to fill in the corresponding fields in these SOCKADDR_IPX structures.
So we reloadThe Socket function is like this.
BOOL Socket (int flg, int nSocketType = SOCK_STREAM, long lEvent =
FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE,
Int nProtocolType = NSPROTO_SPX, int n