In order to let everyone know how WINSAIL schedules TCP/IP in a single-task system, the following explanations are made!
(1) In the CWindow::OnIdle(CObject* pObj) function of the window, the socket loop function pointed to by the TCP/IP loop processing entry function pointer pSocketLoopFc is called.
The source code of CWindow::OnIdle(CObject* pObj) is as follows
extern BOOL bAfxNetcard; // Flag indicating whether a network card is configured in the CONFIG.Sys file
extern BOOL bAfxInitSocket; // Flag indicating whether the socket is successfully initialized
extern BOOL (*__pSocketInitFc)(); // Socket initialization function pointer
extern BOOL (*__pSocketCloseFc)();// Socket closing function pointer
extern BOOL (*__pSocketLoopFc)(BOOL, BOOL, BOOL);// Socket loop function pointer
void CWindow::OnIdle()
{
// Here, it is judged whether the TCP/IP stack needs to be executed
if (bAfxNetcard && bAfxInitSocket && __pSocketLoopFc != NULL)
{
__pSocketLoopFc(TRUE, TRUE, TRUE);
}
// Here, the "idle function pointer" registered by the void CWindow::SetIdleFc() function is executed
if (m_pIdleFc != NULL)
{
m_pIdleFc((CObject*)this);
}
}
(2) The source code of the function AfxRegisterNetcardEntry() for registering the TCP/IP protocol stack is as follows
BOOL AfxRegisterNetcardEntry(BOOL (*pSocketInitFc)(),
BOOL (*pSocketCloseFc)(), BOOL (*pSocketLoopFc)(BOOL, BOOL, BOOL))
{
if (pSocketInitFc == NULL || pSocketCloseFc == NULL)
{
return(FALSE);
}
__pSocketInitFc = pSocketInitFc;
__pSocketCloseFc = pSocketCloseFc;
__pSocketLoopFc = pSocketLoopFc;
return(TRUE);
}
(3) The default in WinSail
The socket initialization function: GlobalInitSocket() function
The socket closing function is: GlobalCloseSocket() function
The socket loop function: EthernetEntry() function
EthernetEntry only processes ARP, RARP, ICMP requests and sends out the packets that have not been sent in time, and other requests are ignored.
So users still need to rewrite their own "socket loop function".
// The following is the user's own "socket loop function". This can refer to the Sail2000.Cpp file and Remote_N.Cpp file of the Sail3000 project, which implements functions such as "file transfer, keyboard key sending, mouse key sending, screen uploading, QQ chatting".
BOOL User_EthernetEntry(BOOL bSingle, BOOL bSend, BOOL bIcmp)
{
// Run the default socket loop function
::EthernetEntry(bSingle, bSend, bIcmp);
// Write your own SOCKET query, read, write, etc. below
// (omitted)
return(TRUE);
}
(4) Since WINSAIL runs in a single task, any long-term blocking anywhere will cause the TCP/IP to be blocked for a long time. In order to reduce this situation, in the blocking loop, you must call
User_EthernetEnty(TRUE, TRUE, TRUE);
(5) If the user registers a third-party TCP/IP stack (such as Watcp, etc.), the initialization function must return TRUE if it is successful, otherwise return FALSE. WinSail automatically sets the return flag of the initialization function to the bAfxInitSocket variable, and don't forget to set the "netCard" key value in the "Netcard" segment of the config.Sys file to TRUE to perfectly integrate with WinSail!
The InitSystem() function in WINSAIL initializes the TCP/IP protocol stack in this way:
bAfxInitSocket = FALSE;
if (bAfxNetcard && __pSocketInitFc != NULL &&
__pSocketCloseFc != NULL)
{
if (!__pSocketInitFc())
{
__pSocketCloseFc();
bAfxInitSocket = FALSE;
//AfxMessageBox("Network","Failed to load network!");
}
else
{
bAfxInitSocket = TRUE;
}
}
[ Last edited by firstsail on 2009-5-16 at 02:25 ]