📄 ddksrvsocket.cpp
字号:
// DDKSrvSocket.cpp: implementation of the CDDKSrvSocket class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
// # of times a connected server socket will loop for without getting any RX data
// before it closes and gets ready to accept new connections again.
#define MAX_IDLE_LOOPS 10
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_DYNAMIC( CDDKSrvSocket, CDDKSocket);
// This server socket object will construct a listen socket of accept a pointer to an existing socket.
CDDKSrvSocket::CDDKSrvSocket(unsigned short port,unsigned long IPAddrULONG /*= ADDR_ANY*/, SOCKET * pServerSocket /*=NULL*/) : CDDKSocket()
{
int error;
CHAR errStr[180],debugStr[180];
INT sockoptEnable = TRUE;
m_serverObject = TRUE;
m_pSocket = NULL;
int check1 = 0x1234;
m_buffer = new char[m_serverBufferSize];
int check2 = 0x1234;
// server stuff
// Create a Thread and then a Server-end socket to listen on later
// create the listening thread
m_listenThreadStatus = SOCKET_EX_PENDING;
m_pWorkerThread = AfxBeginThread((AFX_THREADPROC)SockAsyncFriend,
this,
THREAD_PRIORITY_TIME_CRITICAL, 0,
CREATE_SUSPENDED
);
// construct with IP and port or with an existing socket
if (NULL == pServerSocket)
{
// Setup local addressing for listen socket
m_localSockaddr_in.sin_family = PF_INET;
m_localSockaddr_in.sin_addr.S_un.S_addr = INADDR_ANY; //usually default
if ((m_localSockaddr_in.sin_port = htons((u_short) port)) == 0)
{
sprintf(debugStr, "Cannot use port %ld", port);
OutputDebugString(debugStr);
// Fail the connection process
m_socketStatus = SOCKET_UNCONFIGURED;
return;
}
// Map protocol name to protocol number
if ((m_ppe = getprotobyname("tcp")) == NULL)
{
GetSockError(errStr);
sprintf(debugStr,"Driver cannot connect for listen :%s",errStr);
OutputDebugString(debugStr);
// Fail the connection process
m_socketStatus = SOCKET_UNCONFIGURED;
return;
}
// Allocate a listen socket
m_socket = socket(PF_INET, SOCK_STREAM, m_ppe->p_proto);
// If we could not allocate a socket, we must fail the connection process
if (INVALID_SOCKET == m_socket) // recommended NT error check
{
GetSockError(errStr);
sprintf(debugStr, "Cannot create Listen socket :%s",errStr);
OutputDebugString(debugStr);
// Fail the connection process
m_socketStatus = SOCKET_UNCONFIGURED;
return;
}
// now to bind socket to local address+port
if (0 != bind(m_socket, (sockaddr *)&(m_localSockaddr_in), sizeof(m_localSockaddr_in) ) )
{
GetSockError(errStr);
sprintf(debugStr, "Cannot Bind to Listen socket :%s",errStr);
OutputDebugString(debugStr);
// Fail the connection process
m_socketStatus = SOCKET_UNCONFIGURED;
return;
}
// Set the socket to not delay any sends
error = setsockopt(m_socket, IPPROTO_TCP, TCP_NODELAY, (CHAR FAR * ) &m_sockoptEnable, sizeof (INT));
// If we could not set the socket parameters, we must fail the connection process
if (error == (LONG) SOCKET_ERROR)
{
int lastError = WSAGetLastError();
sprintf(debugStr, "Cannot setsockopt error (%ld)", lastError);
OutputDebugString(debugStr);
// Fail the connection process
m_socketStatus = SOCKET_UNCONFIGURED;
return;
}
m_pSocket = &m_socket;
m_socketStatus = SOCKET_INITIALISED;
}
else
{
// use a socket provided to us.
// do this when many threads listen and accept connections on the same socket.
m_pSocket = pServerSocket;
}
m_socketStatus = SOCKET_INITIALISED;
strcpy(debugStr, "Socket created OK.");
SockDataMessage(debugStr);
m_listenThreadStatus = SOCKET_EX_RUNNING;
}
CDDKSrvSocket::~CDDKSrvSocket()
{
// get the thread to die off
//delete(m_buffer);
//OutputDebugString("In Server socket destructor\n");
m_listenThreadStatus = SOCKET_EX_TERMINATE;
// abort any listen in progress, this only executes on 1st comms thread's socket, since it created it
if (INVALID_SOCKET != m_socket)
{
closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
// wait for thread to die off
CSingleLock lk(&m_threadDeadEvent);
lk.Lock(5000); // wait max 5 seconds
if (NULL != AcceptedAsyncSocket)
{
closesocket(AcceptedAsyncSocket); //kill accepted instance immediately
accepted = FALSE;
OutputDebugString("Server socket closing normally.\n");
SockStateChanged(SOCKETCURRENTLY_CLOSING);
}
}
#ifdef _DEBUG
VOID CDDKSrvSocket::Dump(CDumpContext& dc) const
{
// call the base class first
CDDKSocket::Dump(dc);
// dump our object to the debuggers output
// all important members can be dumped at this stage.
dc << "Server socket: " << "\n";
} // Dump
#endif // _DEBUG
// ------------------------------ SockSockAsyncFriend ------------------------------
UINT SockAsyncFriend(LPVOID pParam)
{
CHAR debugStr2[MAX_DEBUG_STR_LEN];
CHAR debugStr[MAX_DEBUG_STR_LEN];
CDDKSrvSocket* DDKSockPtr;
Sleep(500);
// OK now since everyone will be asking me what is this sleep doing here. So I am
// going to tell U. We are being naughty, this thread actually starts executing
// while the parent class is constructing, consequently all calls to virtual functions
// are made before the parent has initialized completely (constructor body has not yet run)
// and U ned up using un-initialized variables EEK.
DDKSockPtr = (CDDKSrvSocket*)pParam;
try
{
// call the function the thread will run in
if (DDKSockPtr->IsKindOf(RUNTIME_CLASS( CDDKSrvSocket)))
{
CString msgStartup;
// wait untill the Application is ready for us
CSingleLock lk(&DDKSockPtr->m_threadStartupEvent);
lk.Lock(5000); // wait max 5 seconds
msgStartup.Format("Socket %d listen thread ID=%d running",
DDKSockPtr->m_socket,
GetCurrentThreadId());
DDKSockPtr->SockDataMessage(msgStartup);
DDKSockPtr->SockStateChanged(SOCKETCURRENTLY_VOID);
DDKSockPtr->Poll(debugStr);
}
else
{
sprintf(debugStr2, "CDDKSrvSocket SockAsyncFriend pointer corruption!!!!\n");
OutputDebugString(debugStr2);
}
}
catch (...)
{
OutputDebugString( "Catch\n" );
sprintf(debugStr2, "CDDKSrvSocket SockAsyncFriend Exception !!!!\n");
OutputDebugString(debugStr2);
}
try
{
DDKSockPtr->m_listenThreadStatus = SOCKET_EX_TERMINATED;
{
CString d;
d.Format("[Thread %4d Terminating.]\n", GetCurrentThreadId());
OutputDebugString(d);
}
DDKSockPtr->m_threadDeadEvent.SetEvent();// CEvent
}
catch (...)
{
CString msg;
msg.Format("INTERNAL APPLICATION ERROR FILE %s LINE: %d\n%s\n%s",
__FILE__, __LINE__, __MY_APPVERSION__, __DATE__);
OutputDebugString(msg);
}
//AfxEndThread(0);
return(0);
} // SockAsyncFriend
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -