📄 async_full_duplex.shtml.htm
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Zafir Anjum">
<TITLE>Internet - Asynchronous full-duplex connection class</TITLE>
</HEAD>
<body background="../fancyhome/back.gif" tppabs="http://www.codeguru.com/fancyhome/back.gif" bgcolor="#FFFFFF" link="#B50029" vlink="#8E2323" alink="#FF0000">
<table WIDTH="100%">
<tr WIDTH="100%">
<td><td>
</tr>
</table>
<CENTER><H3><FONT COLOR="#AOAO99">Asynchronous full-duplex connection class</FONT></H3></CENTER>
<HR>
<P>This article was contributed by <A HREF="mailto:pbarvinko@yahoo.com">Paul Barvinko</A>.
<P>CInOutConnection is a class that incapsulates Client/Server connection node. It works
in asynchronous full-duplex mode. After initialization it creates four threads: receiving,
sending, working and service threads. First two are obvious, working thread waits for a
message to be posted into input queue and then processes it and service thread could break
connection on inactivity timeout.
<P>For keeping input and output queue in multithreaded environment I created CMessageQueue, which
is simply wrapper under CArray MFC class. The main difference is that before inserting or
removing messages from the queue one should call CMessageQueue::BlockQueue() and then
CMessageQueue::UnBlockQueue(). For single message it could be done via
CMessageQueue::GetFirstMessage() or CMessageQueue::AddSingleMessage() functions. To
determine if there are messages in the queue one should call CMessageQueue::IsQueueFull().
<P>To create new client or server node following steps should be completed:
<P>- Create new class, inherited from CInOutConnection
<P>- Overwrite virtual methods, in order to implement required connection protocol
By default message structure looks like this: <DWORD = frame value for message
identification. Default value = 0x76453201><DWORD = length of the message without frame
value><body background="../fancyhome/back.gif" tppabs="http://www.codeguru.com/fancyhome/back.gif" bgcolor="#FFFFFF" link="#B50029" vlink="#8E2323" alink="#FF0000">. To implement own protocol, one should overwrite
int CInOutConnection::GetHeaderLength()
BOOL CInOutConnection::IsCorrectHeader(char* header)
int CInOutConnection::GetMessageSizeFromHeader(char* header)
void* CInOutConnection::PrepareMessageToSend(void* msg, DWORD length, DWORD& len)
<P>- Determine method of messages processing. Currently there are four ways of received
message notification:
<P>1. void CInOutConnection::ProcessCurrentMessage(void* msg, DWORD length) will be called
on every new message
<P>2. Callback function could be registered for calling on every new message
<P>3. Window procedure could be called with every new message
<P>4. If you wish to manage message receiving from the queue - CInOutConnection::ProcessMessage()
could be overwritten, but in this case this function should retreive messages from input
queue and process them itself.
<P>- If new threads are going to be added to the class - CInOutConnection::AddThread() should
be called at the beginning of the thread function after thread initialization and
CInOutConnection::RemoveThread() on thread function exit. Also one need to overwrite
int CInOutConnection::GetAllThreadsCount() to adjust number of threads to be created. All new
threads should be created in CInOutConnection::CreateThreadsEx().
<P>- To establish connection you should have couple of connected sockets (sending and
receiving) and call CInOutConnection::InitConnection(SOCKET inSocket, SOCKET outSocket). To
terminate connection CInOutConnection::SetTerminate() should be called. To check if the
connection is valid CInOutConnection::IsConnectionValid() should be called. To determine if
thread should be terminated CInOutConnection::Terminate() should be called. Also connection
could be reset by CInOutConnection::ResetConnection().
<P>- After connection termination class owner _MUST_ call CInOutConnection::WaitForTermination().
<P>So the sequence looks like this:
<PRE><TT><FONT COLOR="#990000">
//------------------------------------------------------
//header file:
class CMyConnection : public CInOutConnection
{
public:
.........
}
//cpp-file:
SOCKET inSock, outSock;
CMyConnection cmc;
//..............
//Get sockets connected
//....................
cmc.InitConnection(inSock, outSock);
//...................
//do all the work with connection
//...................
cmc.SetTerminate();
cmc.WaitForTermination(); //!!!!Must have!!!
//-----------------------------------------------------
</FONT></TT></PRE>
<P>Also for receiving, sending and working threads initialization, idle, error and termination
functions could be overwritten.
<PRE><TT><FONT COLOR="#990000">
OnXXXThreadError()
InitXXXThread()
XXXThreadTerminated()
OnXXXThreadIdle()
</FONT></TT></PRE>
<P><A HREF="async_full_duplex.zip" tppabs="http://www.codeguru.com/internet/async_full_duplex.zip">Download source</A>
<P>
<HR>
<TABLE BORDER=0 WIDTH="100%" >
<TR>
<TD WIDTH="33%"><FONT SIZE=-1><A HREF="../index.htm" tppabs="http://www.codeguru.com/">Goto HomePage</A></FONT></TD>
<TD WIDTH="33%">
<CENTER><FONT SIZE=-2>© 1997 Zafir Anjum</FONT> </CENTER>
</TD>
<TD WIDTH="34%">
<DIV ALIGN=right><FONT SIZE=-1>Contact me: <A HREF="mailto:zafir@home.com">zafir@home.com</A> </FONT></DIV>
</TD>
</TR>
</TABLE>
<CENTER><FONT SIZE=-2></FONT></CENTER>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -