Hi again, what I also like to improve on CAsyncSocket:
* You have no GetStatus() to see what the socket is currently doing, if it's created, unconnected, connected, dead..etc. The handle (m_hSocket) doesn't tell you, but in nearly every derived asynchronous socket you need such a status. Also Close() does not call OnClose() which is a little bit anoying... so I always always always add something like this:
Code:
int CMySocket::GetStatus() { return m_nStatus; }
void CMySocket::OnClose(int nErrorCode)
{
if(m_nStatus == SOCKET_DEAD) return;
//Add more code here
CAsyncSocket::OnClose(nErrorCode);
m_nStatus = SOCKET_DEAD;
}
void CMySocket::Close()
{
if (m_hSocket == INVALID_SOCKET) return;
OnClose(0);
CAsyncSocket::Close();
}
Note: This code snippet is just a demonstratation. It's more complex in reality.
* The CAsyncSocket documentation does not mention that you have to override the destructor with something usefull... well maybe it's a C++ pitfall: never expect that a destructor calls a virtual method virtual. In this case it means, the destructor of any CAsynSocket derived class has to call Close();
So two more things I will add in my class....... Moak
PS: An idea from RAM (gtk-gnutella developer), met him on #gnutelladev today: An additional big input buffer on application level. The purpose of such a buffer is to eliminate latencies, those which happens when the TCP/IP stack "ACKs" it's ready for more frames. To avoid latency between starting the data stream again and the first arrival of new frames, the TCP/IP stack requests new data while you still have something in the input buffer (working as a prebuffer cache). I like this idea very much!
Btw GTK uses a kind of reference buffering I mentioned in the first post (see 'Advanced thoughts: Reference buffering' or gtk-gnutella source code).