📄 tcpclient_mod.cpp
字号:
// TcpClient_mod.cpp : Defines the initialization routines for the DLL.
//
#include "stdafx.h"
#include "TcpClient_mod.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//
// Note!
//
// If this DLL is dynamically linked against the MFC
// DLLs, any functions exported from this DLL which
// call into MFC must have the AFX_MANAGE_STATE macro
// added at the very beginning of the function.
//
// For example:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // normal function body here
// }
//
// It is very important that this macro appear in each
// function, prior to any calls into MFC. This means that
// it must appear as the first statement within the
// function, even before any object variable declarations
// as their constructors may generate calls into the MFC
// DLL.
//
// Please see MFC Technical Notes 33 and 58 for additional
// details.
//
/////////////////////////////////////////////////////////////////////////////
// CTcpClient_modApp
BEGIN_MESSAGE_MAP(CTcpClient_modApp, CWinApp)
//{{AFX_MSG_MAP(CTcpClient_modApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CTcpClient_modApp construction
CTcpClient_modApp::CTcpClient_modApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CTcpClient_modApp object
CTcpClient_modApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CTcpClient_modApp initialization
BOOL CTcpClient_modApp::InitInstance()
{
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
return TRUE;
}
/*
* 将新的和SVR的连接加入管理表,对管理表的处理需要同步
*/
bool CTcpClient_modApp::AddSvr(LPCTSTR szIPaddr, UINT nPort, UINT nBuffMax, HWND hWnd,
LPCTSTR initStr, UINT ninitLen)
{
CTcpSvrObj *psvr = NULL;
CSingleLock sLock(&m_svrsMutex);
CString sKey; //用MAP管理表,sKey为搜索的键值
sKey.Format(_T("%s:%d"),szIPaddr,nPort);
sLock.Lock();
if (m_svrs.Lookup(sKey,psvr)) // SVR表已经存在该链路,不可重复连接
{
if (!psvr->_client.IsDead()) // 该链路正常存在
{
sLock.Unlock();
TRACE(_T("%s has been already inserted into svr management map\n"),sKey);
return false;
}
else{// 链路已经牺牲
m_svrs.RemoveKey(sKey);
}
}
psvr = new CTcpSvrObj(szIPaddr, nPort, nBuffMax, hWnd, initStr, ninitLen);
if (psvr == NULL)
{
sLock.Unlock();
return false;
}
if (!psvr->StartUp()) // 启动和服务器的TCP连接
{
delete psvr;
sLock.Unlock();
return false;
}
// 与服务器的TCP连接成功,则将SVR加入管理表
m_svrs.SetAt(sKey,psvr);
sLock.Unlock();
return true;
}
/*
* 移除tcp连接
* 首先关闭该tcp线程
* 然后在管理表中移除该TCP线程
*/
bool CTcpClient_modApp::RemoveSvr(LPCTSTR szIPaddr, UINT nPort)
{
CTcpSvrObj *psvr =NULL;
CSingleLock sLock(&m_svrsMutex);
CString sKey;
sKey.Format(_T("%s:%d"),szIPaddr,nPort);
sLock.Lock();
if (!m_svrs.Lookup(sKey,psvr))
{
sLock.Unlock();
return false;
}
/* if (!psvr->_client.Close()) // 关闭TCP线程
{
sLock.Unlock();
return false;
}
*/ if (!m_svrs.RemoveKey(sKey)) // 在管理表中移除该TCP线程
{
sLock.Unlock();
return false;
}
sLock.Unlock();
return true;
}
bool CTcpClient_modApp::RemoveAllSvr()
{
CSingleLock sLock(&m_svrsMutex);
sLock.Lock();
m_svrs.RemoveAll();
sLock.Unlock();
return true;
}
/*
* 首先,根据IP和端口号查出该连接
* 然后,在连接对应的发送队列加入一块数据,返回
* 调用成功返回 true,否则返回false
*/
bool CTcpClient_modApp::SendToSvr(LPCTSTR szIPaddr, UINT nPort, const char *pMsg, int nLen)
{
CTcpSvrObj *psvr = NULL;
CSingleLock sLock(&m_svrsMutex);
CString sKey;
bool ret;
sKey.Format(_T("%s:%d"),szIPaddr,nPort);
sLock.Lock();
if (!m_svrs.Lookup(sKey,psvr))
{
sLock.Unlock();
return false;
}
ret = psvr->_client.AddSendQueue(pMsg,nLen);
sLock.Unlock();
return ret;
}
/*
* 首先,根据IP和端口号查出该连接
* 然后,取出该连接对应的一块数据,返回
* 调用成功返回 true,否则返回false
*/
bool CTcpClient_modApp::GetSvrBuffData(LPCTSTR szIPaddr, UINT nPort, char * pBuff, int *pLen)
{
CTcpSvrObj *psvr = NULL;
CSingleLock sLock(&m_svrsMutex);
CString sKey;
bool ret;
if (pBuff == NULL || pLen==NULL)
{
return false;
}
sKey.Format(_T("%s:%d"),szIPaddr,nPort);
sLock.Lock();
if (!m_svrs.Lookup(sKey,psvr))
{
sLock.Unlock();
return false;
}
ret = psvr->_client.GetBuff(pBuff,pLen);
sLock.Unlock();
return ret;
}
/*
* CMap模板类的内部元素的析构函数,用于释放CTcpSvrObj指针所对应的内存
*/
template<> void AFXAPI DestructElements<CTcpSvrObj*>(CTcpSvrObj** pElements, int nCount)
{
ASSERT(nCount == 0 ||
AfxIsValidAddress(*pElements, nCount * sizeof(CTcpSvrObj*)));
// call the destructor(s)
for (; nCount--; (*pElements)++)
delete *pElements;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -