You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

421 lines
8.8 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "map.h"
#include "skt.h"
#include "log.h"
#include "manage.h"
#pragma comment(lib, "skt.lib")
#pragma comment(lib,"sysapi.lib")
#pragma comment(lib, "log.lib")
CMapping::CMapping()
{
_brun = false;
_len = 0;
_skt = INVALID_SKT;
_status = Map_NoInit;
_hThread = INVALID_HANDLE;
memset(_msg, 0, MAX_BUF_LEN);
memset(_client, 0, MAX_NAME_LEN);
_hSection = sys_InitializeCriticalSection();
_hSecSend = sys_InitializeCriticalSection();
}
CMapping::~CMapping()
{
Deinit();
sys_DeleteCriticalSection(_hSection);
sys_DeleteCriticalSection(_hSecSend);
}
int CMapping::Init(const char* pszserver/* = 0*/)
{//初始化服务端传入NULL则绑定任意IP自动绑定端口8687
RETURN_CHK_NOPRT(Map_NoInit == _status, 0);
_skt = skt_server(pszserver ? pszserver : ANY_IP, 6050);
if (INVALID_SKT == _skt)
{//创建失败
return -1;
}
ins->m_skt = _skt;
_status = Map_Disconnect; //未连接
StartRun(); //启动任务
return 0;
}
int CMapping::Deinit()
{//关闭连接,反初始化
RETURN_CHK_NOPRT(Map_NoInit != _status, 0);
StopRun(); //停止运行
Clear(); //清空缓冲区
sys_EnterCriticalSection(_hSection);
Close(); //关闭连接
_status = Map_NoInit;
sys_LeaveCriticalSection(_hSection);
return 0;
}
int CMapping::Clear()
{//清空当前缓冲区+发送区
sys_EnterCriticalSection(_hSection);
Release(_vecSet);
sys_LeaveCriticalSection(_hSection);
sys_EnterCriticalSection(_hSecSend);
Release(_vecSend);
sys_LeaveCriticalSection(_hSecSend);
return 0;
}
int CMapping::ReplaceSending()
{//将缓冲区替换发送区
vector<TMappingData>::iterator it;
sys_EnterCriticalSection(_hSection);
sys_EnterCriticalSection(_hSecSend);
Release(_vecSend);
for(it = _vecSet.begin(); it != _vecSet.end(); it++)
{
_vecSend.push_back(*it);
}
_vecSet.clear();
sys_LeaveCriticalSection(_hSection);
sys_LeaveCriticalSection(_hSecSend);
return 0;
}
int CMapping::SetData(int row, int col, const char* pszdata)
{//设置要发送数据 -- 根据行列替换或增加
TMappingData d;
vector<TMappingData>::iterator it;
RETURN_CHK_NOPRT(pszdata, ERR_INPUT_PARAM);
d.len = (int)strlen(pszdata) + 1;
sys_EnterCriticalSection(_hSection);
for(it = _vecSet.begin(); it != _vecSet.end(); it++)
{
if (col == (*it).col && row == (*it).row)
{//find
if ((*it).len < d.len)
{//缓冲区不够
(*it).len = d.len;
delete (*it).pszdata;
(*it).pszdata = new char[d.len];
}
strcpy((*it).pszdata, pszdata);
sys_LeaveCriticalSection(_hSection);
return 0;
}
}
//new
d.col = col;
d.row = row;
d.pszdata = new char[d.len];
strcpy(d.pszdata, pszdata);
_vecSet.push_back(d);
sys_LeaveCriticalSection(_hSection);
return 0;
}
void CMapping::StartRun()
{//任务开始
ZERO_CHK(!_brun);
_brun = true;
_hThread = sys_CreateThread(ThreadFun, this);
}
void CMapping::StopRun()
{//关闭任务
ZERO_CHK(_brun);
_brun = false;
sys_WaitForSingleObject(_hThread);
sys_CloseHandle(_hThread);
}
void CMapping::Close()
{//关闭连接
ZERO_CHK(INVALID_SKT != _skt);
skt_close(_skt);
_skt = INVALID_SKT;
}
void CMapping::Release(vector<TMappingData>& vec)
{//外部加锁
vector<TMappingData>::iterator it;
for(it = vec.begin(); it != vec.end(); it++)
{
FREE_ANY((*it).pszdata);
}
vec.clear();
}
int WINAPI CMapping::ThreadFun(void* param)
{
CMapping* p = (CMapping*)param;
return p->Process();
}
int CMapping::Process()
{
while(_brun)
{//循环
ChkStatus();
RecvMsg();
}
return 0;
}
void CMapping::ChkStatus()
{//检查连接状态
int status = 0;
ushort port = 0;
char ip[MAX_IP_LEN] = {0};
//ZERO_CHK(INVALID_SKT != _skt);
char strbuff[256] = {0};
if (_status == SOCKET_CONNECTED)
{
for (int a = 0;a<ins->m_test_cnt;a++)
{
sprintf(strbuff,"Status#%s$",ins->m_tdata[a].ate);
//SendMsg(strbuff);
}
}
ZERO_CHK(Map_Disconnect == _status);
//休眠
sys_Sleep(50);
status = skt_status(_skt);
ZERO_CHK(SOCKET_CONNECTED == status);
skt_get_addr(_skt, ip, &port);
sprintf(_client, "%s:%d", ip, port);
LOG_INFO("%s Connected", _client);
_status = Map_Connected;
}
int CMapping::FindEnd(const char* pszmsg)
{
int res = 0;
while(*pszmsg)
{
if ('$' == *pszmsg)
{//ok, end flag
break;
}
res++;
pszmsg++;
}
return res;
}
void CMapping::RecvMsg()
{//接收消息
int len = 0;
char* ptmp = NULL;
char* pdest = NULL;
ZERO_CHK(Map_Connected == _status);
pdest = _msg;
len = skt_recv(_skt, _msg + _len, MAX_BUF_LEN - 1 - _len, 100);
if (ERR_NO_CONNECT == len)
{//已经断开
_status = Map_Disconnect;
LOG_INFO("%s Disconnected", _client);
}
ZERO_CHK(len > 0); //error
LOG_INFO("%s recv: %s", _client, _msg + _len);
_len += len; //消息长度
if (MAX_BUF_LEN - 1 == _len)
{//最大长度,不管有没有结束符
LOG_INFO("%s recv: %s not end char", _client, _msg);
_len = 0; //清零
return;
}
while(_len > 0)
{
len = FindEnd(pdest); //查找结束符
if (_len <= len)
{//找到最后的空字符,不算结束符
if (pdest != _msg)
{//指针不等,需要前移
mem_forward(pdest, _len + 1, (uint)(pdest - _msg));
}
return;
}
//新消息
ParseMsg(pdest, len);
_len -= len + 1;
pdest += len + 1;
}
}
void CMapping::SendMsg(const char* psz)
{
int len = (int)strlen(psz);
int ret = skt_send(_skt, psz, len);
if (ret <= 0)
{
LOG_ERR("%s send %s return %d", _client, psz, ret);
}
}
void CMapping::GetAllSendData(char* &psz)
{//获取所有数据传入NULL指针返回new字符串
int len = 0;
vector<TMappingData>::iterator it;
psz = NULL; //fail.
sys_EnterCriticalSection(_hSecSend);
for(it = _vecSend.begin(); it != _vecSend.end(); it++)
{//这里包含分隔符col、row的长度
len += (*it).len + 16;
}
if (0 == len)
{
sys_LeaveCriticalSection(_hSecSend);
return;
}
psz = new char [len];
memset(psz, 0, len);
len = 0;
for(it = _vecSend.begin(); it != _vecSend.end(); it++)
{
len += sprintf(psz + len, "%d,%d,%s;", (*it).row, (*it).col, (*it).pszdata);
}
sprintf(psz + len, "%s", "#");
sys_LeaveCriticalSection(_hSecSend);
}
void CMapping::GetSendData(int col, int row, char* &psz)
{//获取单个数据传入NULL指针返回new字符串
vector<TMappingData>::iterator it;
psz = NULL; //fail.
sys_EnterCriticalSection(_hSecSend);
for(it = _vecSend.begin(); it != _vecSend.end(); it++)
{//这里包含分隔符col、row的长度
if ((*it).col == col && (*it).row == row)
{//find
psz = new char [(*it).len + 16];
sprintf(psz, "%d,%d,%s#", (*it).row, (*it).col, (*it).pszdata);
sys_LeaveCriticalSection(_hSecSend);
return;
}
}
sys_LeaveCriticalSection(_hSecSend);
}
void CMapping::ParseMsg(const char* psz, int len)
{
int col = 0;
int row = 0;
char* ptmp = NULL;
char* pnext = NULL;
char* pszsend = NULL;
char buff[MAX_BUF_LEN] = {0};
ZERO_CHK(len > 0);
strncpy(buff, psz, len); //拷贝消息
if (strstr(buff,"Register") != NULL)
{//status
if(AnalysisRegister(buff) == 0)
SendMsg("Register#1$");
else
SendMsg("Register#0$");
return;
}
if (strstr(buff,"Status") != NULL)
{//获取所有
if(AnslyStatus(buff) == 0)
{
//没有回复
}
}
if (strstr(buff,"StartTest") != NULL)
{//StartTest#761001#1$
}
//
// SendMsg("-1#"); //fail.
//LOG_INFO("%s send: -1#", _client);
}
int CMapping::AnslysisStart(char* buff)
{
return 0;
}
int CMapping::AnalysisRegister(char* buff)
{//Register#761001#761002#761003#761004#761005#761006$
int stemp = 0;
char* p = strtok(buff, "#");
while(p)
{
stemp++;
if (stemp !=1)
{
strcpy(ins->m_tdata[stemp-2].ate,p);
ins->m_tdata[stemp-2].benable = 1;
}
p = strtok(NULL, "#");
}
if (stemp-1>TESTCNT){return 1;}
ins->m_test_cnt = stemp-1;
if(ins->m_test_cnt ==0){return 1;}
return 0;
}
int CMapping::AnslyStatus(char*buff)
{//Status#761001#1$
int stemp = 0;
int stempnum = 0;
char* p = strtok(buff, "#");
while(p)
{
stemp++;
if (stemp ==2)
{
for (int a =0;a<ins->m_test_cnt;a++)
{
if (strcmp(ins->m_tdata[a].ate,p) == 0)
{
stempnum = a;
break;
}
}
}
if (stemp == 3){break;}
p = strtok(NULL, "#");
}
if (stempnum == 0){return 1;}
if (strcmp(p,"0") == 0)
{
ins->m_tdata[stempnum].status = TestRunning;
}
if (strcmp(p,"1") == 0)
{
ins->m_tdata[stempnum].status = TestIdle;
}
return 0;
}