📄 ctcplistener.cpp
字号:
//
// CTCPListener.cpp
//
/*-----------------------------------------------------*\
HQ Tech, Make Technology Easy!
More information, please go to http://hqtech.nease.net.
/*-----------------------------------------------------*/
#include "stdafx.h"
#include "CTCPListener.h"
#include "GlobalDefs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////////////
CTCPListener::CTCPListener()
{
mListener = INVALID_SOCKET;
for (int i = 0; i < MAX_COUNT; i++)
{
mAccepted[i] = INVALID_SOCKET;
}
mListenPort = 10028;
mLsnThread = NULL;
mIsListening = FALSE;
}
CTCPListener::~CTCPListener()
{
DeleteAccepted();
DeleteListener();
StopListening();
}
void CTCPListener::SetListenPort(WORD inPort)
{
mListenPort = inPort;
}
WORD CTCPListener::GetListenPort(void)
{
return mListenPort;
}
// Create a socket and place it in listening state
BOOL CTCPListener::Create(void)
{
DeleteListener();
int val = 0;
BOOL pass = FALSE;
mListener = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (mListener != INVALID_SOCKET)
{
// Settings on socket
BOOL sopt = TRUE;
setsockopt(mListener, IPPROTO_TCP, TCP_NODELAY,
(char *)&sopt, sizeof(BOOL));
setsockopt(mListener, SOL_SOCKET, SO_DONTLINGER,
(char *)&sopt, sizeof(BOOL));
// Bind socket and listen
SOCKADDR_IN addr;
memset(&addr, 0, sizeof(SOCKADDR_IN));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(mListenPort);
val = bind(mListener, (struct sockaddr*) &addr, sizeof(addr));
pass = (val != SOCKET_ERROR);
}
if (pass)
{
// Put the socket into the listening status
val = listen(mListener, SOMAXCONN);
pass = (val != SOCKET_ERROR);
}
if (!pass)
{
DeleteListener();
}
return pass;
}
void CTCPListener::DeleteListener(void)
{
if (mListener != INVALID_SOCKET)
{
closesocket(mListener);
mListener = INVALID_SOCKET;
}
}
void CTCPListener::DeleteAccepted(void)
{
for (int i = 0; i < MAX_COUNT; i++)
{
if (mAccepted[i] != INVALID_SOCKET)
{
closesocket(mAccepted[i]);
mAccepted[i] = INVALID_SOCKET;
}
}
}
BOOL CTCPListener::StartListening(void)
{
// Create socket if necessary
if (mListener == INVALID_SOCKET)
{
Create();
}
if (mListener != INVALID_SOCKET)
{
if (mIsListening)
{
return TRUE;
}
DWORD threadID = 0;
mLsnThread = CreateThread(NULL, 0, ListeningThrd,
this, 0, &threadID);
return (mLsnThread != NULL);
}
return FALSE;
}
void CTCPListener::StopListening(void)
{
if (mListener != INVALID_SOCKET && mIsListening)
{
DeleteListener();
// Make sure the receiving thread has been terminated
if (mLsnThread != NULL)
{
WaitForSingleObject(mLsnThread, INFINITE);
mLsnThread = NULL;
}
}
}
BOOL CTCPListener::Accept(void)
{
if (mListener != INVALID_SOCKET)
{
SOCKADDR_IN saddr;
int len = sizeof(SOCKADDR_IN);
SOCKET accepted = accept(mListener, (SOCKADDR *)&saddr, &len);
if (accepted == INVALID_SOCKET)
{
return FALSE;
}
int index = -1;
for (int i = 0; i < MAX_COUNT; i++)
{
if (mAccepted[i] == INVALID_SOCKET)
{
index = i;
break;
}
}
if (index != -1)
{
mAccepted[index] = accepted;
// Settings on socket
BOOL sopt = TRUE;
setsockopt(accepted, IPPROTO_TCP, TCP_NODELAY,
(char *)&sopt, sizeof(BOOL));
setsockopt(accepted, SOL_SOCKET, SO_DONTLINGER,
(char *)&sopt, sizeof(BOOL));
// Send a message to the controller
Broadcast(msg_TCPSocketAccepted);
return TRUE;
}
else
{
closesocket(accepted);
}
}
return FALSE;
}
// After being fetched out, invalidate the accepted socket
SOCKET CTCPListener::GetAccepted(int index)
{
if (index < MAX_COUNT)
{
SOCKET ret = mAccepted[index];
mAccepted[index] = INVALID_SOCKET;
return ret;
}
return INVALID_SOCKET;
}
BOOL CTCPListener::IsSocketReady(void)
{
for (int i = 0; i < MAX_COUNT; i++)
{
if (mAccepted[i] == INVALID_SOCKET)
{
return FALSE;
}
}
return TRUE;
}
DWORD WINAPI CTCPListener::ListeningThrd(void *pParam)
{
ASSERT(pParam);
CTCPListener * pListen = (CTCPListener *) pParam;
pListen->mIsListening = TRUE;
while (pListen->mIsListening)
{
if (!pListen->Accept())
{
pListen->mIsListening = FALSE;
break;
}
}
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -