diff --git a/VrNets/TCPClient/CMakeLists.txt b/VrNets/TCPClient/CMakeLists.txt index 576b319..af5f018 100644 --- a/VrNets/TCPClient/CMakeLists.txt +++ b/VrNets/TCPClient/CMakeLists.txt @@ -1,8 +1,8 @@ -INCLUDE_DIRECTORIES( - ./_Inc - ./Inc -) - -AUX_SOURCE_DIRECTORY(./Src SrcS) - +INCLUDE_DIRECTORIES( + ./_Inc + ./Inc +) + +AUX_SOURCE_DIRECTORY(./Src SrcS) + ADD_LIBRARY(VrTcpClient STATIC ${SrcS}) \ No newline at end of file diff --git a/VrNets/VrNets.pro b/VrNets/VrNets.pro index 9ca3215..c817f4c 100644 --- a/VrNets/VrNets.pro +++ b/VrNets/VrNets.pro @@ -1,6 +1,6 @@ -TEMPLATE = subdirs - -SUBDIRS += \ - VrModbus.pro \ - VrTcpClient.pro \ - VrTcpServer.pro +TEMPLATE = subdirs + +SUBDIRS += \ + VrModbus.pro \ + VrTcpClient.pro \ + VrTcpServer.pro diff --git a/VrNets/VrTcpServer.pro b/VrNets/VrTcpServer.pro index 768bbfe..4672807 100644 --- a/VrNets/VrTcpServer.pro +++ b/VrNets/VrTcpServer.pro @@ -1,50 +1,50 @@ -QT += core network - -TEMPLATE = lib -CONFIG += c++11 staticlib - -win32-msvc { - QMAKE_CXXFLAGS += /utf-8 -} - -# 源文件 -SOURCES += \ - TCPServer/Src/CYServerTask.cpp \ - TCPServer/Src/CYTCPServer.cpp - -# 头文件 -HEADERS += \ - TCPServer/Inc/IYTCPServer.h \ - TCPServer/_Inc/CYServerTask.h \ - TCPServer/_Inc/CYTCPServer.h - -# 包含路径 -INCLUDEPATH += \ - TCPServer/Inc \ - TCPServer/_Inc - - -INCLUDEPATH += $$PWD/../Utils/VrCommon/Inc -INCLUDEPATH += $$PWD/../Utils/VrUtils/Inc - - -win32:CONFIG(debug, debug|release) { - LIBS += -L../Utils/VrUtils/debug -lVrUtils -}else:win32:CONFIG(release, debug|release){ - LIBS += -L../Utils/VrUtils/release -lVrUtils -}else:unix:!macx { - # Unix/Linux平台库链接(包括交叉编译) - LIBS += -L../Utils/VrUtils -lVrUtils - - # 添加系统库依赖 - LIBS += -lpthread -} - -# 安装路径 -target.path = $$[QT_INSTALL_LIBS] -INSTALLS += target - -# 头文件安装路径 -headers.files = $$HEADERS -headers.path = $$[QT_INSTALL_HEADERS]/VrTcpServer -INSTALLS += headers +QT += core network + +TEMPLATE = lib +CONFIG += c++11 staticlib + +win32-msvc { + QMAKE_CXXFLAGS += /utf-8 +} + +# 源文件 +SOURCES += \ + TCPServer/Src/CYServerTask.cpp \ + TCPServer/Src/CYTCPServer.cpp + +# 头文件 +HEADERS += \ + TCPServer/Inc/IYTCPServer.h \ + TCPServer/_Inc/CYServerTask.h \ + TCPServer/_Inc/CYTCPServer.h + +# 包含路径 +INCLUDEPATH += \ + TCPServer/Inc \ + TCPServer/_Inc + + +INCLUDEPATH += $$PWD/../Utils/VrCommon/Inc +INCLUDEPATH += $$PWD/../Utils/VrUtils/Inc + + +win32:CONFIG(debug, debug|release) { + LIBS += -L../Utils/VrUtils/debug -lVrUtils +}else:win32:CONFIG(release, debug|release){ + LIBS += -L../Utils/VrUtils/release -lVrUtils +}else:unix:!macx { + # Unix/Linux平台库链接(包括交叉编译) + LIBS += -L../Utils/VrUtils -lVrUtils + + # 添加系统库依赖 + LIBS += -lpthread +} + +# 安装路径 +target.path = $$[QT_INSTALL_LIBS] +INSTALLS += target + +# 头文件安装路径 +headers.files = $$HEADERS +headers.path = $$[QT_INSTALL_HEADERS]/VrTcpServer +INSTALLS += headers diff --git a/VrNets/tcpServer/Src/CYServerTask.cpp b/VrNets/tcpServer/Src/CYServerTask.cpp index 5a8d060..ddc4da6 100644 --- a/VrNets/tcpServer/Src/CYServerTask.cpp +++ b/VrNets/tcpServer/Src/CYServerTask.cpp @@ -1,263 +1,263 @@ -#include "CYServerTask.h" - -CYServerTask::CYServerTask() - : m_maxSocket(INVALID_SOCKET) - , m_tTask(nullptr) - , m_bWork(false) - , m_eWorkStatus(WORK_INIT) - , m_fRecv(nullptr) - , m_fException(nullptr) - , m_bUseProtocol(false) -{ - m_vClient.clear(); - FD_ZERO(&m_fdRead); - FD_ZERO(&m_fdExp); - - m_pRecvBuf = new char[RECV_DATA_LEN]; - m_pProtocalHead = new ProtocolHead; -} - -CYServerTask::~CYServerTask() -{ - delete m_tTask; - m_tTask = nullptr; - - m_vClient.clear(); - FD_ZERO(&m_fdRead); - FD_ZERO(&m_fdExp); - - delete[] m_pRecvBuf; - delete m_pProtocalHead; -} - -bool CYServerTask::StartTask(FunTCPServerRecv fRecv, bool bRecvSelfProtocol) -{ - //1初始化线程 - m_bWork = true; - //2赋值回调函数 - m_fRecv = fRecv; - m_bUseProtocol = bRecvSelfProtocol; - - if (!m_tTask) - { - m_tTask = new std::thread(std::mem_fn(&CYServerTask::_OnProcessEvent), this); - m_tTask->detach(); - } - else - { - //发送信号进行初始化 - while (WORK_RUNING != m_eWorkStatus) - { - std::unique_lock lock(m_mutexWork); - m_cvWork.notify_one(); - } - } - - return true; -} - -void CYServerTask::SetExceptionCallback(std::function fException) -{ - m_fException = fException; -} - -bool CYServerTask::StopTask() -{ - m_bWork = false; - ///等待线程开始信号等待处理 - if (m_tTask) - { - while (WORK_WAITSINGAL != m_eWorkStatus) - { - std::chrono::milliseconds milTime(10); - std::this_thread::sleep_for(milTime); - } - m_fRecv = nullptr; - delete m_tTask; - m_tTask = nullptr; - } - return true; -} - -///添加客户端 -bool CYServerTask::AddClient(TCPClient * pClient) -{ - if(nullptr != pClient && m_vClient.size() < FD_SETSIZE) - { - std::lock_guard mLck(m_mClient); - //��¼Task�еĿͻ��� - m_vClient.push_back(pClient); - //���ӵ�select��fd������ - FD_SET(pClient->m_nFD, &m_fdRead); - FD_SET(pClient->m_nFD, &m_fdExp); - //�ҵ����FD - m_maxSocket = m_maxSocket > pClient->m_nFD ? m_maxSocket : pClient->m_nFD; - return true; - } - else - { - return false; - } -} - -///移除客户端 -bool CYServerTask::DelClient(const TCPClient * pClient) -{ - bool bRet = false; - std::lock_guard mLck(m_mClient); - std::vector::iterator iter = m_vClient.begin(); - m_maxSocket = INVALID_SOCKET; - while (iter != m_vClient.end()) - { - if (*iter == pClient) - { - m_vClient.erase(iter); - FD_CLR(pClient->m_nFD, &m_fdRead); - FD_CLR(pClient->m_nFD, &m_fdExp); - bRet = true; - break; - } - } - - iter = m_vClient.begin(); - while (iter != m_vClient.end()) - { - //����ͳ�����ֵ - m_maxSocket = m_maxSocket > (*iter)->m_nFD ? m_maxSocket : (*iter)->m_nFD; - iter++; - } - return bRet; -} - -///获取Task中客户端的数目 -int CYServerTask::GetClientNum() -{ - return (int)m_vClient.size(); -} - -void CYServerTask::_OnProcessEvent() -{ - while (true) - { - if (!m_bWork) - { - m_eWorkStatus = WORK_WAITSINGAL; - std::unique_lock lock(m_mutexWork); - m_cvWork.wait(lock); - if (WORK_CLOSE == m_eWorkStatus) - { - break; - } - else - { - m_eWorkStatus = WORK_RUNING; - } - } - else - { - if (m_vClient.empty()) - { - std::chrono::milliseconds milTime(1); - std::this_thread::sleep_for(milTime); - continue; - } - - - ///临时客户端vector - std::vector vTCPClient; - fd_set fdRead; - fd_set fdExp; - { - std::unique_lock lock(m_mClient); - vTCPClient = m_vClient; - fdRead = m_fdRead; - fdExp = m_fdExp; - } - - struct timeval sWaitTime = { 0, 1000 }; - int nCount = select((int)m_maxSocket + 1, &fdRead, nullptr, &fdExp, &sWaitTime); - - if (nCount <= 0) - { - continue; - } - - for (int i = (int)vTCPClient.size() - 1; i >= 0; i--) - { - TCPClient* tmpClient = vTCPClient[i]; - if (FD_ISSET(tmpClient->m_nFD, &fdRead)) - { - //���ܲ��ص� - if (!_OnProcessData(tmpClient)) - { - if (m_fException) - { - m_fException(tmpClient); - } - } - } - } - } - } - m_eWorkStatus = WORK_EXIT; -} - -bool CYServerTask::_OnProcessData(TCPClient* pClient) -{ - const int nRecvLen = RECV_DATA_LEN; - - //��Э����� - if(!m_bUseProtocol) - { - int nCount = recv(pClient->m_nFD, m_pRecvBuf, nRecvLen, 0); - - if (nCount > 0 && m_fRecv) - { - m_fRecv(pClient, m_pRecvBuf, nCount); - } - return nCount > 0; - } - - //Э����� - int nAllDataLen = 0; - int recv_len = 0; - int nRet = 0; - - int nDataAddr = 6 * sizeof(int); - - //recv head - do - { - if ((recv_len = recv(pClient->m_nFD, (char *)(m_pProtocalHead) + nAllDataLen, nDataAddr - nAllDataLen, 0)) <= 0) - { - printf("read head failed \n"); - return false; - } - nAllDataLen += recv_len; - } while (nAllDataLen < nDataAddr); - - - nAllDataLen = 0; - //recv data - while (nAllDataLen < m_pProtocalHead->nLen) - { - recv_len = recv(pClient->m_nFD, (char *)(m_pProtocalHead) + nDataAddr + nAllDataLen, - m_pProtocalHead->nLen - nAllDataLen, 0); - if (recv_len <= 0) - { - printf("read data len : %d failed [%d]\n", m_pProtocalHead->nLen - nAllDataLen, recv_len); - return false; - } - - nAllDataLen += recv_len; - } - nAllDataLen = 0; - - if (m_fRecv) - { - m_fRecv(pClient, (char *)m_pProtocalHead, m_pProtocalHead->nLen + nDataAddr); - } - - //printf("cmd = %x len = %d \n", protocol.nCmd, protocol.nLen); - return 0 == nRet; -} +#include "CYServerTask.h" + +CYServerTask::CYServerTask() + : m_maxSocket(INVALID_SOCKET) + , m_tTask(nullptr) + , m_bWork(false) + , m_eWorkStatus(WORK_INIT) + , m_fRecv(nullptr) + , m_fException(nullptr) + , m_bUseProtocol(false) +{ + m_vClient.clear(); + FD_ZERO(&m_fdRead); + FD_ZERO(&m_fdExp); + + m_pRecvBuf = new char[RECV_DATA_LEN]; + m_pProtocalHead = new ProtocolHead; +} + +CYServerTask::~CYServerTask() +{ + delete m_tTask; + m_tTask = nullptr; + + m_vClient.clear(); + FD_ZERO(&m_fdRead); + FD_ZERO(&m_fdExp); + + delete[] m_pRecvBuf; + delete m_pProtocalHead; +} + +bool CYServerTask::StartTask(FunTCPServerRecv fRecv, bool bRecvSelfProtocol) +{ + //1初始化线程 + m_bWork = true; + //2赋值回调函数 + m_fRecv = fRecv; + m_bUseProtocol = bRecvSelfProtocol; + + if (!m_tTask) + { + m_tTask = new std::thread(std::mem_fn(&CYServerTask::_OnProcessEvent), this); + m_tTask->detach(); + } + else + { + //发送信号进行初始化 + while (WORK_RUNING != m_eWorkStatus) + { + std::unique_lock lock(m_mutexWork); + m_cvWork.notify_one(); + } + } + + return true; +} + +void CYServerTask::SetExceptionCallback(std::function fException) +{ + m_fException = fException; +} + +bool CYServerTask::StopTask() +{ + m_bWork = false; + ///等待线程开始信号等待处理 + if (m_tTask) + { + while (WORK_WAITSINGAL != m_eWorkStatus) + { + std::chrono::milliseconds milTime(10); + std::this_thread::sleep_for(milTime); + } + m_fRecv = nullptr; + delete m_tTask; + m_tTask = nullptr; + } + return true; +} + +///添加客户端 +bool CYServerTask::AddClient(TCPClient * pClient) +{ + if(nullptr != pClient && m_vClient.size() < FD_SETSIZE) + { + std::lock_guard mLck(m_mClient); + //��¼Task�еĿͻ��� + m_vClient.push_back(pClient); + //���ӵ�select��fd������ + FD_SET(pClient->m_nFD, &m_fdRead); + FD_SET(pClient->m_nFD, &m_fdExp); + //�ҵ����FD + m_maxSocket = m_maxSocket > pClient->m_nFD ? m_maxSocket : pClient->m_nFD; + return true; + } + else + { + return false; + } +} + +///移除客户端 +bool CYServerTask::DelClient(const TCPClient * pClient) +{ + bool bRet = false; + std::lock_guard mLck(m_mClient); + std::vector::iterator iter = m_vClient.begin(); + m_maxSocket = INVALID_SOCKET; + while (iter != m_vClient.end()) + { + if (*iter == pClient) + { + m_vClient.erase(iter); + FD_CLR(pClient->m_nFD, &m_fdRead); + FD_CLR(pClient->m_nFD, &m_fdExp); + bRet = true; + break; + } + } + + iter = m_vClient.begin(); + while (iter != m_vClient.end()) + { + //����ͳ�����ֵ + m_maxSocket = m_maxSocket > (*iter)->m_nFD ? m_maxSocket : (*iter)->m_nFD; + iter++; + } + return bRet; +} + +///获取Task中客户端的数目 +int CYServerTask::GetClientNum() +{ + return (int)m_vClient.size(); +} + +void CYServerTask::_OnProcessEvent() +{ + while (true) + { + if (!m_bWork) + { + m_eWorkStatus = WORK_WAITSINGAL; + std::unique_lock lock(m_mutexWork); + m_cvWork.wait(lock); + if (WORK_CLOSE == m_eWorkStatus) + { + break; + } + else + { + m_eWorkStatus = WORK_RUNING; + } + } + else + { + if (m_vClient.empty()) + { + std::chrono::milliseconds milTime(1); + std::this_thread::sleep_for(milTime); + continue; + } + + + ///临时客户端vector + std::vector vTCPClient; + fd_set fdRead; + fd_set fdExp; + { + std::unique_lock lock(m_mClient); + vTCPClient = m_vClient; + fdRead = m_fdRead; + fdExp = m_fdExp; + } + + struct timeval sWaitTime = { 0, 1000 }; + int nCount = select((int)m_maxSocket + 1, &fdRead, nullptr, &fdExp, &sWaitTime); + + if (nCount <= 0) + { + continue; + } + + for (int i = (int)vTCPClient.size() - 1; i >= 0; i--) + { + TCPClient* tmpClient = vTCPClient[i]; + if (FD_ISSET(tmpClient->m_nFD, &fdRead)) + { + //���ܲ��ص� + if (!_OnProcessData(tmpClient)) + { + if (m_fException) + { + m_fException(tmpClient); + } + } + } + } + } + } + m_eWorkStatus = WORK_EXIT; +} + +bool CYServerTask::_OnProcessData(TCPClient* pClient) +{ + const int nRecvLen = RECV_DATA_LEN; + + //��Э����� + if(!m_bUseProtocol) + { + int nCount = recv(pClient->m_nFD, m_pRecvBuf, nRecvLen, 0); + + if (nCount > 0 && m_fRecv) + { + m_fRecv(pClient, m_pRecvBuf, nCount); + } + return nCount > 0; + } + + //Э����� + int nAllDataLen = 0; + int recv_len = 0; + int nRet = 0; + + int nDataAddr = 6 * sizeof(int); + + //recv head + do + { + if ((recv_len = recv(pClient->m_nFD, (char *)(m_pProtocalHead) + nAllDataLen, nDataAddr - nAllDataLen, 0)) <= 0) + { + printf("read head failed \n"); + return false; + } + nAllDataLen += recv_len; + } while (nAllDataLen < nDataAddr); + + + nAllDataLen = 0; + //recv data + while (nAllDataLen < m_pProtocalHead->nLen) + { + recv_len = recv(pClient->m_nFD, (char *)(m_pProtocalHead) + nDataAddr + nAllDataLen, + m_pProtocalHead->nLen - nAllDataLen, 0); + if (recv_len <= 0) + { + printf("read data len : %d failed [%d]\n", m_pProtocalHead->nLen - nAllDataLen, recv_len); + return false; + } + + nAllDataLen += recv_len; + } + nAllDataLen = 0; + + if (m_fRecv) + { + m_fRecv(pClient, (char *)m_pProtocalHead, m_pProtocalHead->nLen + nDataAddr); + } + + //printf("cmd = %x len = %d \n", protocol.nCmd, protocol.nLen); + return 0 == nRet; +} diff --git a/VrNets/tcpServer/_Inc/CYServerTask.h b/VrNets/tcpServer/_Inc/CYServerTask.h index e3161f1..171d46e 100644 --- a/VrNets/tcpServer/_Inc/CYServerTask.h +++ b/VrNets/tcpServer/_Inc/CYServerTask.h @@ -1,113 +1,113 @@ -#pragma once -#include -#include -#include -#include -#include -#ifndef _WIN32 -#include -#include -#endif // !_WIN32 - -#include "IYTCPServer.h" - -typedef std::function FunTCPServerRecv; - -#define RECV_DATA_LEN 12 * 1024 * 1024 - -#ifdef _WIN32 - -#define FD_SETSIZE 1024 -#define _WINSOCK_DEPRECATED_NO_WARNINGS -#include -#include - -#pragma comment(lib, "ws2_32.lib") - -#else -#define SOCKET int -#define INVALID_SOCKET (SOCKET)(~0) -#define SOCKET_ERROR (-1) -#endif - -enum WORK_STATUS -{ - WORK_INIT, - WORK_RUNING, - WORK_WAITSINGAL, - WORK_CLOSE, - WORK_EXIT, -}; - -class CYServerTask -{ -public: - CYServerTask(); - ~CYServerTask(); - - /// 开始任务 - bool StartTask(FunTCPServerRecv fRecv, bool bRecvSelfProtocol = false); - - ///设置异常处理回调(给CYTCPServer使用) - void SetExceptionCallback(std::function fException); - - ///ֹͣ���� - bool StopTask(); - - ///添加客户端 - bool AddClient(TCPClient* pClient); - - ///移除客户端 - bool DelClient(const TCPClient* pClient); - - ///获取Task中客户端的数目 - int GetClientNum(); - -private: - void _OnProcessEvent(); - - bool _OnProcessData(TCPClient* pClient); - -private: - - ///客户端存储vector - std::mutex m_mClient; - std::vector m_vClient; - - ///select 监听 注释:和m_vClient使用同一把锁 - int m_maxSocket; - fd_set m_fdRead; - fd_set m_fdExp; - - ///线程管理 - std::thread* m_tTask; - bool m_bWork; - WORK_STATUS m_eWorkStatus; - - //工作信号 - std::mutex m_mutexWork; - std::condition_variable m_cvWork; - - //处理回调[接口] -private: - //处理回调[接口] - FunTCPServerRecv m_fRecv; - std::function m_fException; - char* m_pRecvBuf; - - std::atomic m_bUseProtocol; - - struct ProtocolHead - { - int nHead; - int nTime; - int nCmd; - int nDef; - int nLen; - int nTail; - char pData[RECV_DATA_LEN]; - }; - - ProtocolHead* m_pProtocalHead; - -}; +#pragma once +#include +#include +#include +#include +#include +#ifndef _WIN32 +#include +#include +#endif // !_WIN32 + +#include "IYTCPServer.h" + +typedef std::function FunTCPServerRecv; + +#define RECV_DATA_LEN 12 * 1024 * 1024 + +#ifdef _WIN32 + +#define FD_SETSIZE 1024 +#define _WINSOCK_DEPRECATED_NO_WARNINGS +#include +#include + +#pragma comment(lib, "ws2_32.lib") + +#else +#define SOCKET int +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR (-1) +#endif + +enum WORK_STATUS +{ + WORK_INIT, + WORK_RUNING, + WORK_WAITSINGAL, + WORK_CLOSE, + WORK_EXIT, +}; + +class CYServerTask +{ +public: + CYServerTask(); + ~CYServerTask(); + + /// 开始任务 + bool StartTask(FunTCPServerRecv fRecv, bool bRecvSelfProtocol = false); + + ///设置异常处理回调(给CYTCPServer使用) + void SetExceptionCallback(std::function fException); + + ///ֹͣ���� + bool StopTask(); + + ///添加客户端 + bool AddClient(TCPClient* pClient); + + ///移除客户端 + bool DelClient(const TCPClient* pClient); + + ///获取Task中客户端的数目 + int GetClientNum(); + +private: + void _OnProcessEvent(); + + bool _OnProcessData(TCPClient* pClient); + +private: + + ///客户端存储vector + std::mutex m_mClient; + std::vector m_vClient; + + ///select 监听 注释:和m_vClient使用同一把锁 + int m_maxSocket; + fd_set m_fdRead; + fd_set m_fdExp; + + ///线程管理 + std::thread* m_tTask; + bool m_bWork; + WORK_STATUS m_eWorkStatus; + + //工作信号 + std::mutex m_mutexWork; + std::condition_variable m_cvWork; + + //处理回调[接口] +private: + //处理回调[接口] + FunTCPServerRecv m_fRecv; + std::function m_fException; + char* m_pRecvBuf; + + std::atomic m_bUseProtocol; + + struct ProtocolHead + { + int nHead; + int nTime; + int nCmd; + int nDef; + int nLen; + int nTail; + char pData[RECV_DATA_LEN]; + }; + + ProtocolHead* m_pProtocalHead; + +};