概述
QT-C++多线程TCP客户端
- 前言
- 1.效果预览
- 2.核心程序
- 3.程序下载
前言
将接收消息和发送消息分别用不同线程处理,支持服务器掉线客户端重新连接机制,内置自动消息发送和接收处理方式,内置心跳包发送。
提示:以下是本篇文章正文内容,下面案例可供参考
1.效果预览
2.核心程序
代码如下:
// 发送线程
DWORD WINAPI cSocketClient::sendCmdDataThread(LPVOID lpParam)
{
cSocketClient *pMain = (cSocketClient*)lpParam;
int nStep = 0;
sUnChokeTimer timer[2];
int nReConnectTimes = 3 * 1000;
int nHeatTickTimes = 10 * 1000;
cSendInfo sendInfo;
while (true)
{
if (pMain->isRelease())
return 0;
else
QThread::msleep(5);
switch (nStep)
{
case 0:
{
// 等待连接
if (!pMain->isConnected())
QThread::msleep(500);
else
{
timer[1].start(nHeatTickTimes);
nStep = 1;
}
}break;
case 1:
{
// 判断服务器掉线,需要重连接
if (!pMain->isConnected() && !pMain->d_ptr->strIp.isEmpty())
{
timer[0].start(nReConnectTimes);
nStep = 2;
}
else
{
nStep = 3;
}
}break;
case 2:
{
if (timer[0].isTimeOut())
{
// 重连接
pMain->connect(pMain->d_ptr->strIp, pMain->d_ptr->nPort);
nStep = 1;
}
}break;
case 3:
{
if (pMain->d_ptr->strSendDataList.size() > 0)
{
// 发送消息队列的消息
QString strData("");
pMain->operaterSendDataList(OP_TAKE_FIRST, strData);
pMain->sendData(pMain->d_ptr->socket, (char*)strData.toLocal8Bit().toStdString().c_str(), strData.toLocal8Bit().toStdString().size());
// 有消息就重新计时,心跳重发时间
timer[1].start(nHeatTickTimes);
}
nStep = 4;
}break;
case 4:
{
// 长时间无消息,发送心跳包
if (timer[1].isTimeOut())
{
QString strData = sendInfo.heartBeat();
pMain->operaterSendDataList(OP_APPEND, strData);
}
nStep = 5;
}break;
case 5:
{
// 处理从服务器接收回来的数据包
QString strData("");
pMain->operaterReiceveBuffer(OP_TAKE_FIRST, strData);
pMain->dealRecieveInfo(strData);
nStep = 6;
}break;
default:
nStep = 1;
break;
}
}
return 0;
}
// 接收线程
DWORD WINAPI cSocketClient::recieveCmdDataThread(LPVOID lpParam)
{
cSocketClient *pMain = (cSocketClient*)lpParam;
int nStep = 0;
while (true)
{
// 资源退出,线程也退出
if (pMain->isRelease())
return 0;
else
QThread::msleep(5);
switch (nStep)
{
case 0:
{
// 等待连接
if (!pMain->isConnected())
QThread::msleep(500);
else
nStep = 1;
}break;
case 1:
{
// 设置接收不阻塞
u_long ioMode = 1;
::ioctlsocket((SOCKET)pMain->d_ptr->socket, FIONBIO, (u_long FAR*)&ioMode);
nStep = 2;
}break;
case 2:
{
// 接收服务端数据
memset(pMain->d_ptr->chReciveBuff, '