190 lines
4.1 KiB
C++
190 lines
4.1 KiB
C++
// CCEXPipe.cpp : 定义 DLL 应用程序的入口点。
|
||
//
|
||
|
||
#include "stdafx.h"
|
||
#include "CCEXPipeServer.h"
|
||
#include <process.h>
|
||
#include <stdlib.h>
|
||
|
||
|
||
CCEXPipeServerBase* CCEXPipeServerBase::CreateObj()
|
||
{
|
||
return new CCEXPipeServer();
|
||
}
|
||
|
||
CCEXPipeServer::CCEXPipeServer()
|
||
{
|
||
m_hServerThr = NULL;
|
||
|
||
m_bActive = FALSE;
|
||
|
||
m_lPort = 0;
|
||
|
||
m_socket = -1;
|
||
|
||
m_LisentSock = -1;
|
||
|
||
InitializeCriticalSection(&m_cySocket);
|
||
}
|
||
|
||
CCEXPipeServer::~CCEXPipeServer()
|
||
{
|
||
DeleteCriticalSection(&m_cySocket);
|
||
}
|
||
|
||
BOOL CCEXPipeServer::SendeData(const char* pData, int lLen)
|
||
{
|
||
EnterCriticalSection(&m_cySocket);
|
||
if (-1 == m_socket)
|
||
{
|
||
LeaveCriticalSection(&m_cySocket);
|
||
return FALSE;
|
||
}
|
||
|
||
BOOL bRes = ::SendeData(m_socket, pData, lLen);
|
||
|
||
LeaveCriticalSection(&m_cySocket);
|
||
|
||
return bRes;
|
||
}
|
||
|
||
BOOL CCEXPipeServer::SendeMsg(int lMsgId, const char* pData, int lLen)
|
||
{
|
||
PIPE_DATA_STRUCT* pstSend = (PIPE_DATA_STRUCT*)new char[sizeof(PIPE_DATA_STRUCT) + lLen - sizeof(char[4])];
|
||
pstSend->lMsgId = lMsgId;
|
||
pstSend->lDataLen = lLen;
|
||
if (NULL != pData)
|
||
{
|
||
memcpy(&pstSend->acData, pData, lLen);
|
||
}
|
||
BOOL bRes = SendeData((const char*)pstSend, sizeof(PIPE_DATA_STRUCT) + lLen - sizeof(char[4]));
|
||
delete [] (char*)pstSend;
|
||
pstSend = NULL;
|
||
|
||
return bRes;
|
||
}
|
||
|
||
unsigned int __stdcall g_PipServerThr(void* pPara)
|
||
{
|
||
return ((CCEXPipeServer*)pPara)->ServerThr();
|
||
}
|
||
|
||
BOOL CCEXPipeServer::Start(const char* pPipeName)
|
||
{
|
||
if (TRUE == m_bActive)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
//由于windows管道为半双工,底层不使用管道了,直接使用socket
|
||
m_bActive = TRUE;
|
||
m_lPort = atoi(pPipeName);
|
||
m_LisentSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||
int opt = 1;
|
||
setsockopt(m_LisentSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt));
|
||
SOCKADDR_IN stAddr;
|
||
ZeroMemory(&stAddr, sizeof(stAddr)); /*空间地址结构体所在的内存空间。*/
|
||
stAddr.sin_family=AF_INET; /*填充地址与端口的信息。*/
|
||
stAddr.sin_port=htons(m_lPort); /*端口。*/
|
||
stAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
|
||
if (SOCKET_ERROR == bind(m_LisentSock, (SOCKADDR*)&stAddr, sizeof(SOCKADDR_IN)))
|
||
{
|
||
LogOutToFile("CCEXPipeServer::ServerThr bind error.[%d]",GetLastError());
|
||
closesocket(m_LisentSock);
|
||
return FALSE;
|
||
}
|
||
|
||
if (SOCKET_ERROR == listen(m_LisentSock, 1))
|
||
{
|
||
LogOutToFile("CCEXPipeServer::ServerThr listen error.[%d]",GetLastError());
|
||
closesocket(m_LisentSock); //关闭套接字
|
||
return FALSE;
|
||
}
|
||
|
||
m_hServerThr = (HANDLE)_beginthreadex(NULL, 0, g_PipServerThr, this, 0, NULL);
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL CCEXPipeServer::SleepForActive(int lMs)
|
||
{
|
||
for (int i = 0; i < lMs && TRUE == m_bActive; i+=20)
|
||
{
|
||
Sleep(lMs);
|
||
}
|
||
return m_bActive;
|
||
}
|
||
|
||
unsigned int CCEXPipeServer::ServerThr()
|
||
{
|
||
char* pReadBuf = new char[MAX_PIP_BUF];
|
||
HANDLE hEvent = NULL;
|
||
for (;m_bActive;)
|
||
{
|
||
//等待连接
|
||
SOCKADDR_IN stNewAddr = {0};
|
||
int lNewAddrLen = sizeof(SOCKADDR_IN);
|
||
m_socket = accept(m_LisentSock, (struct sockaddr *)&stNewAddr, &lNewAddrLen);
|
||
if (SOCKET_ERROR == m_socket)
|
||
{
|
||
LogOutToFile("CCEXPipeServer::ServerThr accept error.[%d]",GetLastError());
|
||
SleepForActive(2000);
|
||
continue;
|
||
}
|
||
|
||
//通知窗口线程,有客户端连接了
|
||
m_pCallBackFun(m_pCallBackObj, CEXPIPE_NEW_CLIENT, NULL, NULL);
|
||
|
||
for (;;)
|
||
{
|
||
int lRead = 0;
|
||
memset(pReadBuf, 0, MAX_PIP_BUF);
|
||
//从命名管道中读取数据
|
||
if(FALSE == ReadPipePacket(m_socket, pReadBuf, MAX_PIP_BUF-1, lRead))
|
||
{
|
||
//PostMessage(m_hWnd, WM_PIPE_DIS_CLIENT, (WPARAM)this, (LPARAM)NULL);
|
||
m_pCallBackFun(m_pCallBackObj, CEXPIPE_DIS_CLIENT, (WPARAM)this, (LPARAM)NULL);
|
||
break;
|
||
}
|
||
|
||
pReadBuf[lRead] = '\0';
|
||
|
||
m_pCallBackFun(m_pCallBackObj, CEXPIPE_NEW_DATA, (WPARAM)pReadBuf, (LPARAM)lRead);
|
||
}
|
||
closesocket(m_socket);
|
||
m_socket = SOCKET_ERROR;
|
||
}
|
||
|
||
delete [] pReadBuf;
|
||
LogOutToFile("CCEXPipeServer::ServerThr 退出[%d]", GetLastError());
|
||
|
||
m_hServerThr = NULL;
|
||
|
||
return 0;
|
||
}
|
||
|
||
BOOL CCEXPipeServer::Stop()
|
||
{
|
||
if (NULL == m_hServerThr)
|
||
{
|
||
//已经停止了
|
||
return FALSE;
|
||
}
|
||
|
||
m_bActive = FALSE;
|
||
closesocket(m_LisentSock);
|
||
closesocket(m_socket);
|
||
if (WAIT_TIMEOUT == WaitForSingleObject(m_hServerThr, 2000))
|
||
{
|
||
LogOutToFile("ERROR: CCEXPipeServer::Stop timeout\r\n");
|
||
TerminateThread(m_hServerThr, 0);
|
||
m_hServerThr = NULL;
|
||
}
|
||
m_hServerThr = NULL;
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
|
||
|