//mthserver.cpp
#include "TcpServer.h"
#include "CLogFile.h"
#include <string>
#include <pthread.h>
#include <vector>
CLogFile logfile;
TcpServer tcpServer;
std::vector<long> vpthids; //儲存執行緒id
void mainEXIT(int sig)
{
if(sig>0)
{
signal(sig,SIG_IGN);
signal(SIGINT,SIG_IGN);
signal(SIGTERM,SIG_IGN);
printf("mthserver exit..(PID=%d)\n",getpid());
logfile.Write("mthserver exit..(PID=%d)\n",getpid());
tcpServer.CloseListen();
for(auto& pthid:vpthids)
{
pthread_cancel(pthid);
}
std::vector<long>(0).swap(vpthids);
exit(0);
}
}
void pthExit(void* arg)
{
int sockfd=(int)(long)arg;
close(sockfd);
for(auto iter=vpthids.begin();iter!=vpthids.end();iter++)
{
if(*iter==pthread_self())
vpthids.erase(iter);
}
logfile.Write("thread clean..\n") ;
}
bool biz002(const char* strRecvBuffer,char* strSendBuffer)
{
char msg[1024];
memset(msg,0,sizeof(msg));
GetXmlBuffer(strRecvBuffer,"message",msg,1023);
strcat(msg," ok");
sprintf(strSendBuffer,"<retcode>0</retcode><message>%s</message>",msg);
return true;
}
//業務1(business001)處理函式
bool biz001(const char* strRecvBuffer,char* strSendBuffer)
{
//從strRecvBuffer中解析出username欄位和password欄位的值
char username[51],password[51];
memset(username,0,sizeof(username));
memset(password,0,sizeof(password));
GetXmlBuffer(strRecvBuffer,"username",username,50);
GetXmlBuffer(strRecvBuffer,"password",password,50);
//將使用者名稱、密碼同資料庫中值對比
if((strcmp(username, "wk")==0)&&(strcmp(password, "p@ssw0rd")==0))
sprintf(strSendBuffer,"<retcode>0</retcode><message>login success</message>");
else
sprintf(strSendBuffer,"<retcode>-1</retcode><message>使用者名稱或密碼不正確</message>");
return true;
}
//心跳響應
bool biz000(const char* strRecvBuffer,char* strSendBuffer)
{
sprintf(strSendBuffer, "<retcode>0</retcode><message>heartbeat success</message>");
return true;
}
//業務處理函式
//strRecvBuffer-接收報文
//strSendBuffer-傳送報文
bool BusinessProcess(const char* strRecvBuffer,char* strSendBuffer)
{
int ibizcode=-1;
GetXmlBuffer(strRecvBuffer,"bizcode",&ibizcode);
switch(ibizcode)
{
case 0:
return biz000(strRecvBuffer,strSendBuffer); //心跳
break;
case 1:
return biz001(strRecvBuffer,strSendBuffer); //登入
break;
case 2:
return biz002(strRecvBuffer,strSendBuffer); //業務2
break;
default:
logfile.Write("非法報文:%s\n",strSendBuffer);
return false;
}
}
void* thmainfunc(void* arg)
{
pthread_detach(pthread_self());
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
pthread_cleanup_push(pthExit,arg);
char strRecvBuffer[1024];
char strSendBuffer[1024];
int sockfd=(int)(long)arg;
while(true)
{
memset(strRecvBuffer,0,sizeof(strRecvBuffer));
memset(strSendBuffer,0,sizeof(strSendBuffer));
int iBufferlen;
if(tcpServer.TcpRead(sockfd,strRecvBuffer, &iBufferlen,300)==false) //超過60s沒有收到心跳報文,就斷開連線
break;
logfile.Write("recv msg:%s\n",strRecvBuffer);
//業務處理
if(BusinessProcess(strRecvBuffer,strSendBuffer)==false)
pthread_exit(0);
logfile.Write("send msg:%s\n",strSendBuffer);
if(tcpServer.TcpWrite(sockfd,strSendBuffer)==false)
break;
}
logfile.Write("client(%s) disconnected..\n", tcpServer.GetIP());
pthread_cleanup_pop(1);
pthread_exit(0);
}
int main(int argc, char** argv)
{
if(argc!=3)
{
printf("Using: ./mthserver port logfile\nExample:./mthserver 5000 /tmp/mthserver.log\n\n");
return -1;
}
for(int i=0;i<70;i++)
{
signal(i, SIG_IGN);
}
logfile.m_bBackup=false; //多程序服務程式關閉日誌切換
if(logfile.Open(argv[2], "a+") == false) //a+新增,不存在則建立
{
printf("logfile open failed..(%s)\n", argv[2]);
}
signal(SIGINT,mainEXIT);
signal(SIGTERM,mainEXIT);
if(tcpServer.InitServer(atoi(argv[1]))==false)
{
logfile.Write("server init failed..\n");
mainEXIT(-1);
}
while(true)
{
if(tcpServer.Accept()==false)
{
logfile.Write("client(%s) connected failed..\n", tcpServer.GetIP());
continue;
}
logfile.Write("client(%s) connected..\n", tcpServer.GetIP());
pthread_t pthid;
if(pthread_create(&pthid,NULL,thmainfunc,(void*)(long)tcpServer.m_clientfd)!=0)
{
logfile.Write("create thread failed..\n");
return -1;
}
vpthids.push_back(pthid);
}
return 0;
}