// CCEXPipe.cpp : 定义 DLL 应用程序的入口点。 // #include "stdafx.h" #include "CCEXPipeServer.h" #include #include 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; }