将接收消息和发送消息分别用不同线程处理,支持服务器掉线客户端重新连接机制,内置自动消息发送和接收处理方式,内置心跳包发送。
提示:以下是本篇文章正文内容,下面案例可供参考
代码如下:
// 发送线程 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, '\0', sizeof(pMain->d_ptr->chReciveBuff)); int nRecieveSize = ::recv(pMain->d_ptr->socket, pMain->d_ptr->chReciveBuff, MAX_BUFF_SIZE, NULL);; if (nRecieveSize > 0) { pMain->d_ptr->chReciveBuff[nRecieveSize] = '\0'; std::string str(pMain->d_ptr->chReciveBuff, nRecieveSize); pMain->operaterReiceveBuffer(OP_APPEND, QString::fromLocal8Bit(str.data())); emit pMain->signalRevieveInfo(QString::fromLocal8Bit(str.data())); } else if (nRecieveSize == SERVER_NO_LINE) { // 服务端掉线 pMain->close(); nStep = 0; } }break; default: nStep = 1; break; } } return 0; }t
https://download.csdn.net/download/u013083044/21910665