// CTcpServer
// 可以收发网络消息, 同时可接收文件,支持断点续传,支持同时接收多个文件
//
#include "stdafx.h"
#include "TcpServer.h"
#include "SysUtils.h"
#pragma comment(lib, "Ws2_32.lib")
/////////////////////////////////////////////////////////////////////////
// CTcpServer
/////////////////////////////////////////////////////////////////////////
CTcpServer::CTcpServer(void *pNotifyObj)
{
ASSERT(pNotifyObj != NULL);
memset(&m_WSAData, 0, sizeof(WSADATA));
m_pNotifyObj = pNotifyObj;
strcpy(m_szBindIpAddr, "");
m_wPort = DFT_PORT;
m_nSendTimeOut = DFT_SENDTIMEOUT;
m_dwProgressTimeInterval = DFT_PROGRESSTIMEINTERVAL;
m_nAcceptThreadPriority = DFT_ACCEPTTHREADPRIORITY;
m_nSocketRecvThreadPriority = DFT_SOCKETRECVTHREADPRIORITY;
// 初始化事件指针
m_OnAccept = NULL;
m_OnAcceptErr = NULL;
m_OnSocketConnect = NULL;
m_OnSocketClose = NULL;
m_OnOneNetMsg = NULL;
m_OnRecvFileRequest = NULL;
m_OnRecvFileProgress = NULL;
m_OnRecvFileSucc = NULL;
m_OnRecvFileFail = NULL;
StartupSocket(); // 初始化windows socket
RegisterAcceptWndClass(); // 注册用于接收socket连接的窗体类
RegisterRecvWndClass(); // 注册用于接收数据的窗体类
RegisterFileRecverWndClass(); // 注册用于文件接收器的窗体类
m_pAcceptSocket = new CAcceptSocket(this, m_pNotifyObj); // 接收socket连接的socket对象
}
CTcpServer::~CTcpServer(void)
{
StopAccept(); // 停止接收socket连接
CancelAllRecvFile(); // 取消所有的文件接收
CloseAllServerClientSocket(); // 关闭所有的客户端连接
UnregisterClass(STR_RECVHIDEWNDCLASSNAME, AfxGetInstanceHandle());
UnregisterClass(STR_ACCEPTHIDEWNDCLASSNAME, AfxGetInstanceHandle());
UnregisterClass(STR_FILERECVERHIDEWNDCLASSNAME, AfxGetInstanceHandle());
CleanupSocket();
// 关闭并删除接受socket对象
delete m_pAcceptSocket;
m_pAcceptSocket = NULL;
}
// 初始化windows socket
BOOL CTcpServer::StartupSocket(void)
{
int nErrCode = 0;
if(m_WSAData.wVersion == 0)
{
nErrCode = WSAStartup(0x0101, &m_WSAData);
if(nErrCode != 0)
memset(&m_WSAData, 0, sizeof(WSADATA));
}
return (nErrCode == 0);
}
// 清除windows socket
void CTcpServer::CleanupSocket(void)
{
if(m_WSAData.wVersion != 0)
{
WSACleanup();
memset(&m_WSAData, 0, sizeof(WSADATA));
}
}
// 关闭所有的客户端socket连接
void CTcpServer::CloseAllServerClientSocket(void)
{
CServerClientSocket *pServerClientSocket;
while(!m_ServerClientSockets.IsEmpty())
{
pServerClientSocket = m_ServerClientSockets.RemoveHead();
delete pServerClientSocket;
}
}
// 注册用于接收线程连接的窗体类
BOOL CTcpServer::RegisterAcceptWndClass(void)
{
WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
wc.lpfnWndProc = (WNDPROC)(CAcceptSocket::HideWndProc);
wc.hInstance = AfxGetInstanceHandle();
wc.lpszClassName = STR_ACCEPTHIDEWNDCLASSNAME;
return (RegisterClass(&wc) != 0);
}
// 注册用于接收数据的窗体类
BOOL CTcpServer::RegisterRecvWndClass(void)
{
WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
wc.lpfnWndProc = (WNDPROC)(CServerClientSocket::HideWndProc);
wc.hInstance = AfxGetInstanceHandle();
wc.lpszClassName = STR_RECVHIDEWNDCLASSNAME;
return (RegisterClass(&wc) != 0);
}
// 注册用于文件接收器的窗体类
BOOL CTcpServer::RegisterFileRecverWndClass(void)
{
WNDCLASS wc;
memset(&wc, 0, sizeof(WNDCLASS));
wc.lpfnWndProc = (WNDPROC)(CFileRecver::HideWndProc);
wc.hInstance = AfxGetInstanceHandle();
wc.lpszClassName = STR_FILERECVERHIDEWNDCLASSNAME;
return (RegisterClass(&wc) != 0);
}
// 开始接收socket连接
BOOL CTcpServer::StartAccept(void)
{
StopAccept();
m_pAcceptSocket->SetBindIpAddr(m_szBindIpAddr);
m_pAcceptSocket->SetPort(m_wPort);
m_pAcceptSocket->SetAcceptThreadPriority(m_nAcceptThreadPriority);
m_pAcceptSocket->SetOnAccept(m_OnAccept);
m_pAcceptSocket->SetOnAcceptErr(m_OnAcceptErr);
m_pAcceptSocket->SetOnSocketConnect(m_OnSocketConnect);
return m_pAcceptSocket->StartAccept();
}
// 停止接收socket连接
void CTcpServer::StopAccept(void)
{
m_pAcceptSocket->StopAccept();
}
// 添加socket对象
CServerClientSocket *CTcpServer::AddServerClientSocket(SOCKET hSocket)
{
// 创建socket对象
CServerClientSocket *pServerClientSocket = new CServerClientSocket(this, m_pNotifyObj);
pServerClientSocket->SetSocketHandle(hSocket);
pServerClientSocket->SetSendTimeOut(m_nSendTimeOut);
pServerClientSocket->SetProgressTimeInterval(m_dwProgressTimeInterval);
pServerClientSocket->SetSocketRecvThreadPriority(m_nSocketRecvThreadPriority);
pServerClientSocket->SetOnSocketClose(m_OnSocketClose);
pServerClientSocket->SetOnOneNetMsg(m_OnOneNetMsg);
pServerClientSocket->SetOnRecvFileRequest(m_OnRecvFileRequest);
pServerClientSocket->SetOnRecvFileProgress(m_OnRecvFileProgress);
pServerClientSocket->SetOnRecvFileSucc(m_OnRecvFileSucc);
pServerClientSocket->SetOnRecvFileFail(m_OnRecvFileFail);
// 初始化接收socket
if(!pServerClientSocket->InitServerClientSocket())
{
delete pServerClientSocket;
return NULL;
}
// 添加到列表
m_ServerClientSockets.AddTail(pServerClientSocket);
return pServerClientSocket;
}
// 移除客户端socket对象
void CTcpServer::RemoveServerClientSocket(CServerClientSocket *pServerClientSocket)
{
POSITION pos;
pos = m_ServerClientSockets.Find(pServerClientSocket);
if(pos != NULL)
m_ServerClientSockets.RemoveAt(pos);
}
// 取消所有的接收
void CTcpServer::CancelAllRecvFile(void)
{
CServerClientSocket *pServerClientSocket;
POSITION pos;
pos = m_ServerClientSockets.GetHeadPosition();
for(int i = 0; i < m_ServerClientSockets.GetCount(); i++)
{
pServerClientSocket = m_ServerClientSockets.GetNext(pos);
pServerClientSocket->CancelRecvFile();
}
}
// 获取客户端数目
int CTcpServer::GetClientCount(void)
{
return m_ServerClientSockets.GetCount();
}
void CTcpServer::SetBindIpAddr(char *szBindIpAddr)
{
strcpy(m_szBindIpAddr, szBindIpAddr);
}
void CTcpServer::SetPort(WORD wPort)
{
m_wPort = wPort;
}
void CTcpServer::SetSendTimeOut(int nSendTimeOut)
{
m_nSendTimeOut = nSendTimeOut;
}
void CTcpServer::SetProgressTimeInterval(DWORD dwProgressTimeInterval)
{
m_dwProgressTimeInterval = dwProgressTimeInterval;
}
void CTcpServer::SetAcceptThreadPriority(int nPriority)
{
m_nAcceptThreadPriority = nPriority;
}
void CTcpServer::SetSocketRecvThreadPriority(int nPriority)
{
m_nSocketRecvThreadPriority = nPriority;
}
void CTcpServer::SetOnAccept(AcceptFun OnAccept)
{
m_OnAccept = OnAccept;
}
void CTcpServer::SetOnAcceptErr(AcceptErrFun OnAcceptErr)
{
m_OnAcceptErr = OnAcceptErr;
}
void CTcpServer::SetOnSocketConnect(SocketConnectFun OnSocketConnect)
{
m_OnSocketConnect = OnSocketConnect;
}
void CTcpServer::SetOnSocketClose(SocketCloseFun OnSocketClose)
{
m_OnSocketClose = OnSocketClose;
}
void CTcpServer::SetOnOneNetMsg(OneNetMsgFun OnOneNetMsg)
{
m_OnOneNetMsg = OnOneNetMsg;
}
void CTcpServer::SetOnRecvFileRequest(RecvFileRequestFun OnRecvFileRequest)
{
m_OnRecvFileRequest = OnRecvFileRequest;
}
void CTcpServer::SetOnRecvFileProgress(RecvFileProgressFun OnRecvFileProgress)
{
m_OnRecvFileProgress = OnRecvFileProgress;
}
void CTcpServer::SetOnRecvFileSucc(RecvFileSuccFun OnRecvFileSucc)
{
m_OnRecvFileSucc = OnRecvFileSucc;
}
void CTcpServer::SetOnRecvFileFail(RecvFileFailFun OnRecvFileFail)
{
m_OnRecvFileFail = OnRecvFileFail;
}
/////////////////////////////////////////////////////////////////////////
// CAcceptSocket
/////////////////////////////////////////////////////////////////////////
// 隐藏窗体消息处理函数
LRESULT CAcceptSocket::HideWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CAcceptSocket *pAcceptSocket = (CAcceptSocket *)lParam;
switch(uMsg)
{
case WM_ACCEPT:
pAcceptSocket->HandleAcceptMsg(wParam); // wParam为新socket句柄
break;
case WM_ACCEPTERR:
pAcceptSocket->HandleAcceptErrMsg();
break;