socketDemo/serverHeartbeat.cpp
2024-09-12 18:03:40 +08:00

171 lines
4.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// tcp服务端增加了心跳报文。
#include "_el.h"
using namespace eviwbh;
ctcpserver tcpserver; // 创建服务端对象。
clogfile logfile; // 服务程序的运行日志。
void FathEXIT(int sig); // 父进程退出函数。
void ChldEXIT(int sig); // 子进程退出函数。
string strsendbuffer; // 发送报文的buffer。
string strrecvbuffer; // 接收报文的buffer。
bool bizmain(); // 业务处理主函数。
int main(int argc,char *argv[])
{
if (argc!=4)
{
printf("Using:./demo06 port logfile timeout\n");
printf("Example:./demo06 5005 /log/idc/demo06.log 10\n\n");
return -1;
}
// 关闭全部的信号和输入输出。
// 设置信号,在shell状态下可用 "kill + 进程号" 正常终止些进程
// 但请不要用 "kill -9 +进程号" 强行终止
//closeioandsignal(false);
signal(SIGINT,FathEXIT); signal(SIGTERM,FathEXIT);
if (logfile.open(argv[2])==false) { printf("logfile.open(%s) failed.\n",argv[2]); return -1; }
// 服务端初始化。
if (tcpserver.initserver(atoi(argv[1]))==false)
{
logfile.write("tcpserver.initserver(%s) failed.\n",argv[1]); return -1;
}
while (true)
{
// 获取客户端的连接请求。
if (tcpserver.accept()==false)
{
logfile.write("tcpserver.accept() failed.\n"); FathEXIT(-1);
}
logfile.write("客户端(%s已连接。\n",tcpserver.getip());
if (fork()>0) { tcpserver.closeclient(); continue; } // 父进程继续回到accept()。
// 子进程重新设置退出信号。
signal(SIGINT,ChldEXIT); signal(SIGTERM,ChldEXIT);
tcpserver.closelisten(); // 子进程关闭监听的socket。
while (true)
{
// 子进程与客户端进行通讯,处理业务。
if (tcpserver.read(strrecvbuffer,atoi(argv[3]))==false)
{
logfile.write("tcpserver.read() failed.\n"); ChldEXIT(0);
}
logfile.write("接收:%s\n",strrecvbuffer.c_str());
bizmain(); // 业务处理主函数。
if (tcpserver.write(strsendbuffer)==false)
{
logfile.write("tcpserver.send() failed.\n"); ChldEXIT(0);
}
logfile.write("发送:%s\n",strsendbuffer.c_str());
}
ChldEXIT(0);
}
}
// 父进程退出函数。
void FathEXIT(int sig)
{
// 以下代码是为了防止信号处理函数在执行的过程中被信号中断。
signal(SIGINT,SIG_IGN); signal(SIGTERM,SIG_IGN);
logfile.write("父进程退出sig=%d。\n",sig);
tcpserver.closelisten(); // 关闭监听的socket。
kill(0,15); // 通知全部的子进程退出。
exit(0);
}
// 子进程退出函数。
void ChldEXIT(int sig)
{
// 以下代码是为了防止信号处理函数在执行的过程中被信号中断。
signal(SIGINT,SIG_IGN); signal(SIGTERM,SIG_IGN);
logfile.write("子进程退出sig=%d。\n",sig);
tcpserver.closeclient(); // 关闭客户端的socket。
exit(0);
}
void login(); // 登录。
void check_balance(); // 查询余额。
void transfer(); // 转帐。
bool businessmain() // 业务处理主函数。
{
int id; // 业务代码。
getxmlbuffer(strrecvbuffer,"id",id);
switch(id)
{
case 1: // 登录。
login();
break;
case 2: // 查询余额。
check_balance();
break;
case 3: // 转帐。
transfer();
break;
default: // 非法报文。
strsendbuffer="<retcode>9</retcode><message>业务不存在。</message>";
break;
}
return true;
}
void login() // 登录。
{
string username,password;
getxmlbuffer(strrecvbuffer,"username",username);
getxmlbuffer(strrecvbuffer,"password",password);
if ( (username=="0369") && (password=="3690") )
strsendbuffer="<retcode>0</retcode><message>成功。</message>";
else
strsendbuffer="<retcode>-1</retcode><message>用户名或密码不正确。</message>";
}
void check_balance() // 查询余额。
{
string cardid;
getxmlbuffer(strrecvbuffer,"cardid",cardid); // 获取卡号。
// 假装操作了数据库,得到了卡的余额。
strsendbuffer="<retcode>0</retcode><ye>128.83</ye>";
}
void transfer() // 转帐。
{
string cardid1,cardid2;
getxmlbuffer(strrecvbuffer,"cardid1",cardid1);
getxmlbuffer(strrecvbuffer,"cardid2",cardid2);
double transfer;
getxmlbuffer(strrecvbuffer,"transfer",transfer);
// 假装操作了数据库,更新了两个账户的金额,完成了转帐操作。
if ( transfer<100 )
strsendbuffer="<retcode>0</retcode><message>成功。</message>";
else
strsendbuffer="<retcode>-1</retcode><message>余额不足。</message>";
}