修改文件结束符

This commit is contained in:
yiyi 2026-02-21 00:20:51 +08:00
parent 02a9537377
commit 362e92661e
5 changed files with 439 additions and 439 deletions

View File

@ -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})

View File

@ -1,6 +1,6 @@
TEMPLATE = subdirs
SUBDIRS += \
VrModbus.pro \
VrTcpClient.pro \
VrTcpServer.pro
TEMPLATE = subdirs
SUBDIRS += \
VrModbus.pro \
VrTcpClient.pro \
VrTcpServer.pro

View File

@ -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

View File

@ -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<std::mutex> lock(m_mutexWork);
m_cvWork.notify_one();
}
}
return true;
}
void CYServerTask::SetExceptionCallback(std::function<void(const TCPClient*)> 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<std::mutex> mLck(m_mClient);
//<2F><>¼Task<73>еĿͻ<C4BF><CDBB><EFBFBD>
m_vClient.push_back(pClient);
//<2F><><EFBFBD>ӵ<EFBFBD>select<63><74>fd<66><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FD_SET(pClient->m_nFD, &m_fdRead);
FD_SET(pClient->m_nFD, &m_fdExp);
//<2F>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>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<std::mutex> mLck(m_mClient);
std::vector<TCPClient*>::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())
{
//<2F><><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>ֵ
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<std::mutex> 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<TCPClient*> vTCPClient;
fd_set fdRead;
fd_set fdExp;
{
std::unique_lock<std::mutex> 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))
{
//<2F><><EFBFBD>ܲ<EFBFBD><DCB2>ص<EFBFBD>
if (!_OnProcessData(tmpClient))
{
if (m_fException)
{
m_fException(tmpClient);
}
}
}
}
}
}
m_eWorkStatus = WORK_EXIT;
}
bool CYServerTask::_OnProcessData(TCPClient* pClient)
{
const int nRecvLen = RECV_DATA_LEN;
//<2F><>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD>
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;
}
//Э<><D0AD><EFBFBD><EFBFBD><EFBFBD>
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<std::mutex> lock(m_mutexWork);
m_cvWork.notify_one();
}
}
return true;
}
void CYServerTask::SetExceptionCallback(std::function<void(const TCPClient*)> 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<std::mutex> mLck(m_mClient);
//<2F><>¼Task<73>еĿͻ<C4BF><CDBB><EFBFBD>
m_vClient.push_back(pClient);
//<2F><><EFBFBD>ӵ<EFBFBD>select<63><74>fd<66><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
FD_SET(pClient->m_nFD, &m_fdRead);
FD_SET(pClient->m_nFD, &m_fdExp);
//<2F>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>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<std::mutex> mLck(m_mClient);
std::vector<TCPClient*>::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())
{
//<2F><><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD>ֵ
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<std::mutex> 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<TCPClient*> vTCPClient;
fd_set fdRead;
fd_set fdExp;
{
std::unique_lock<std::mutex> 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))
{
//<2F><><EFBFBD>ܲ<EFBFBD><DCB2>ص<EFBFBD>
if (!_OnProcessData(tmpClient))
{
if (m_fException)
{
m_fException(tmpClient);
}
}
}
}
}
}
m_eWorkStatus = WORK_EXIT;
}
bool CYServerTask::_OnProcessData(TCPClient* pClient)
{
const int nRecvLen = RECV_DATA_LEN;
//<2F><>Э<EFBFBD><D0AD><EFBFBD><EFBFBD><EFBFBD>
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;
}
//Э<><D0AD><EFBFBD><EFBFBD><EFBFBD>
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;
}

View File

@ -1,113 +1,113 @@
#pragma once
#include <vector>
#include <mutex>
#include <thread>
#include <atomic>
#include <condition_variable>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#endif // !_WIN32
#include "IYTCPServer.h"
typedef std::function<void (const TCPClient* pClient, const char* pData, const unsigned int nLen)> FunTCPServerRecv;
#define RECV_DATA_LEN 12 * 1024 * 1024
#ifdef _WIN32
#define FD_SETSIZE 1024
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <windows.h>
#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<void(const TCPClient*)> fException);
///ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
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<TCPClient *> 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<void(const TCPClient*)> m_fException;
char* m_pRecvBuf;
std::atomic<bool> 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 <vector>
#include <mutex>
#include <thread>
#include <atomic>
#include <condition_variable>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#endif // !_WIN32
#include "IYTCPServer.h"
typedef std::function<void (const TCPClient* pClient, const char* pData, const unsigned int nLen)> FunTCPServerRecv;
#define RECV_DATA_LEN 12 * 1024 * 1024
#ifdef _WIN32
#define FD_SETSIZE 1024
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <windows.h>
#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<void(const TCPClient*)> fException);
///ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
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<TCPClient *> 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<void(const TCPClient*)> m_fException;
char* m_pRecvBuf;
std::atomic<bool> m_bUseProtocol;
struct ProtocolHead
{
int nHead;
int nTime;
int nCmd;
int nDef;
int nLen;
int nTail;
char pData[RECV_DATA_LEN];
};
ProtocolHead* m_pProtocalHead;
};