void* tcpRecvThread::action() { OutPutDebugStringToCMD( "Recv Thread action!\n" ); while(1) { for ( int i = 0; i < getThreadOwner()->getMaxConn(); i++ ) { do { TCPConnection* conInfo = getThreadOwner()->getConn( i ); if ( !conInfo ) break; if ( conInfo->m_State != enTCPConnectionState_Connected ) break; char recvBuff[MAX_RECVPACK] = {0}; TCPNetPack* pNetPack = (TCPNetPack*)recvBuff; pNetPack->ConnectionID = i; //int recvRet = recv( conInfo->m_Socket, pNetPack->buff, MAX_RECVPACK, 0 ); int recvRet = recv( conInfo->m_Socket, pNetPack->buff, MAX_RECVPACK, 0 ); if ( 0 > recvRet ) { #ifdef WIN32 if (GetLastError() != WSAEWOULDBLOCK) #else if (errno == EWOULDBLOCK) #endif { OutPutLastErrorMsgToCMD(); closeConnect(conInfo); break; } if(UNIX_TIME_STAMP - conInfo->m_lastPingTimeStamp > KEEP_ALIVE_TIME) { OutPutDebugStringToCMD("close socket: client long time send no pack\n"); closeConnect(conInfo); break; } } else if ( 0 < recvRet ) { //OutPutDebugStringToCMD("Recv data:%s\n", pNetPack->buff ); conInfo->m_lastPingTimeStamp = UNIX_TIME_STAMP; getThreadOwner()->PushDataToRecvBuff( recvBuff, recvRet + 4 ); break; } else if (0 == recvRet) { OutPutDebugStringToCMD("close socket: client close socket\n"); closeConnect(conInfo); } } while (0); } Sleep(20); } }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); this->setWindowIcon(QIcon(":/resource/icon/telescope.png")); this->setWindowTitle(tr("Telescope")); //For common initialization isConnected = false; hostIsSet = false; client= NULL; background=QImage(":/resource/image/colourback.jpg"); net.setParentWidget(this); connect(&net,SIGNAL(hideIMSignal()),this,SLOT(hideIM())); //For exit Tool ui->actionExit->setIcon(QIcon(":/resource/icon/exit.png")); ui->actionExit->setStatusTip(tr("Exit from Telescope.")); connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(closeClient())); //For connect Tool ui->actionConnect->setIcon(QIcon(":/resource/icon/connect.png")); ui->actionConnect->setStatusTip(tr("Set up connection.")); connect(ui->actionConnect, SIGNAL(triggered()), this, SLOT(getConnectInfo())); //For IM Tool ui->actionIM->setIcon(QIcon(":/resource/icon/chat2.png")); ui->actionIM->setStatusTip(tr("Open the IM Dialog.")); ui->actionIM->setCheckable(true); //单击后保持按下状态 connect(ui->actionIM,SIGNAL(triggered()),this,SLOT(showIM())); //For disconnect Tool ui->actionDisConnect->setIcon(QIcon(":/resource/icon/disconnect.png")); ui->actionDisConnect->setStatusTip(tr("Close up connection.")); connect(ui->actionDisConnect, SIGNAL(triggered()), this, SLOT(closeConnect())); //For ToolBar ui->mainToolBar->setMovable(false); //固定工具栏 ui->mainToolBar->addAction(ui->actionConnect); ui->mainToolBar->addAction(ui->actionIM); ui->mainToolBar->addAction(ui->actionDisConnect); ui->mainToolBar->addAction(ui->actionExit); ui->mainToolBar->setIconSize(QSize(50,45)); //设置工具栏图标大小 //For MainWindow setAttribute(Qt::WA_TranslucentBackground); //窗口半透明 setWindowFlags(Qt::Window | Qt::FramelessWindowHint); //无边框窗口 //For central Widget shPic = new ShowPic(this); //shPic->setMinimumSize(QSize(80, 60)); this->setCentralWidget(shPic); }
// 收到内部服务发往网络客户端的消息 int CSrvMsgHandler::onServiceMessage(const char* msgData, const unsigned int msgLen, const char* userData, const unsigned int userDataLen, unsigned short dstProtocolId, unsigned int srcSrvId, unsigned short srcSrvType, unsigned short srcModuleId, unsigned short srcProtocolId, int userFlag, unsigned int msgId, const char* srvAsyncDataFlag, unsigned int srvAsyncDataFlagLen) { if (dstProtocolId >= MaxProtocolIDCount) { OptErrorLog("receive error service msg, srcServiceId = %d, srcServiceType = %d, dstProtocolId = %d", srcSrvId, srcSrvType, dstProtocolId); return InvalidParam; } // 服务要求停止连接代理 if (srcProtocolId == ConnectProxyOperation::StopProxy) return stopServiceConnect(srcSrvId); IndexToConnects::iterator it = m_idx2Connects.find(userFlag); if (it == m_idx2Connects.end()) { int rc = sendMessage(NULL, 0, userFlag, NULL, 0, srcSrvId, 0, 0, ConnectProxyOperation::PassiveClosed, 0); // 通知服务,对应的连接已经被关闭了 OptErrorLog("can not find the connect proxy data, srcServiceId = %d, srcServiceType = %d, dstProtocolId = %d, userFlag = %d, rc = %d", srcSrvId, srcSrvType, dstProtocolId, userFlag, rc); return InvalidParam; } if (srcProtocolId != ConnectProxyOperation::ActiveClosed) { // 服务消息转发给网络客户端 if (srcSrvType == ServiceType::GameHallSrv) srcSrvId = m_gameHallId; // 游戏大厅 sendMsgToClient(msgData, msgLen, dstProtocolId, it->second.conn, srcSrvId, srcModuleId, msgId); } else { // 这里不可以调用 resetUserData(it->second.conn, NULL) 屏蔽回调; 之后接着调用 closeConnect(it->second.conn),然后删除连接数据 // 实际上存在客户端和这里同时关闭连接的情况,因此可能在 resetUserData 之前,连接挂接的数据已经被连接线程放入队列里了 // 这样的话会导致连接关闭函数 onClosedConnect 被回调时传递的参数是无效的,访问无效参数则直接崩溃 it->second.serviceId2ConnectIdx.erase(srcSrvId); // 连接被服务主动关闭了 OptWarnLog("to do active close connect, srcSrvId = %d, userFlag = %d, ip = %s, port = %d, isEmpty = %d, index = %d", srcSrvId, userFlag, CSocket::toIPStr(it->second.conn->peerIp), it->second.conn->peerPort, it->second.serviceId2ConnectIdx.empty(), it->second.index); if (it->second.serviceId2ConnectIdx.empty()) closeConnect(it->second.conn); // 该连接没有服务对应了,则关闭连接 } return Success; }
void CSrvMsgHandler::onUnLoad(const char* srvName, const unsigned int srvId, unsigned short moduleId) { // 服务退出,关闭所有在线连接 for (IndexToConnects::iterator connIt = m_idx2Connects.begin(); connIt != m_idx2Connects.end(); ++connIt) { for (ServiceIDToConnectIdx::iterator it = connIt->second.serviceId2ConnectIdx.begin(); it != connIt->second.serviceId2ConnectIdx.end(); ++it) { // 通知各个服务,对应的连接已经被关闭了 sendMessage(NULL, 0, connIt->second.index, NULL, 0, it->first, 0, 0, ConnectProxyOperation::PassiveClosed, 0); } resetUserData(connIt->second.conn, NULL); // 屏蔽连接关闭时的回调动作 closeConnect(connIt->second.conn); } m_idx2Connects.clear(); m_redisDbOpt.disconnectSvr(); }
void* tcpSendThread::action() { OutPutDebugStringToCMD( "Send Thread action!\n" ); while(1) { do { unsigned int datasize = 0; const void* data = getThreadOwner()->GetDataFromSendBuff( datasize ); if ( !data ) break; TCPNetPack* netPack = (TCPNetPack*)data; TCPConnection* conn = getThreadOwner()->getConn( netPack->ConnectionID ); if( !conn ) break; if ( conn->m_State != enTCPConnectionState_Connected ) break; int sendsize = send( conn->m_Socket, (const char*)(netPack->buff), datasize-4, MSG_NOSIGNAL ); if ( sendsize == SOCKET_ERROR ) { #ifdef WIN32 if (GetLastError() != WSAEWOULDBLOCK) #else if (errno == EWOULDBLOCK) #endif { OutPutLastErrorMsgToCMD(); closeConnect(conn); } } } while (0); Sleep(30); } }
// 停止该服务的所有连接 int CSrvMsgHandler::stopServiceConnect(unsigned int srcSrvId) { OptWarnLog("stop service connect, id = %u", srcSrvId); // 关闭该服务的所有连接 for (IndexToConnects::iterator connIt = m_idx2Connects.begin(); connIt != m_idx2Connects.end(); ++connIt) { ServiceIDToConnectIdx::iterator srvIdxIt = connIt->second.serviceId2ConnectIdx.find(srcSrvId); if (srvIdxIt != connIt->second.serviceId2ConnectIdx.end()) { // 这里不可以调用 resetUserData(it->second.conn, NULL) 屏蔽回调; 之后接着调用 closeConnect(it->second.conn),然后删除连接数据 // 实际上存在客户端和这里同时关闭连接的情况,因此可能在 resetUserData 之前,连接挂接的数据已经被连接线程放入队列里了 // 这样的话会导致连接关闭函数 onClosedConnect 被回调时传递的参数是无效的,访问无效参数则直接崩溃 // 也因此这里不能调用 m_idx2Connects.erase(connIt++); 来删除连接数据,必须在回调函数 onClosedConnect 里调用 connIt->second.serviceId2ConnectIdx.erase(srvIdxIt); // 连接被服务主动关闭了 if (connIt->second.serviceId2ConnectIdx.empty()) closeConnect(connIt->second.conn); // 该连接没有服务对应了,则关闭连接 } } return Success; }
ConnectDb::~ConnectDb() { closeConnect(); }
ui->pushButton_weigh->setEnabled(true);//TODO:test to change true.should be delete; emit sendConnectSocket(_GroupIpList); emit sendConnectSocketReturn(ui->combGroup->currentText().toInt(),true); }); connect(ui->pushButton_close,&QPushButton::clicked,[=]{ QSettings setting;//将对应每一项当前连接状态保存到setting里,以便后面读取及更新界面UI setting.beginGroup(QString("GroupData/%1").arg(ui->combGroup->currentText())); setting.setValue("States",flag);//此处只保存当前组号连接状态 setting.sync();//立即更新以保存 setting.endGroup(); ui->pushButton_link->setEnabled(true); ui->pushButton_close->setEnabled(false); ui->pushButton_put->setEnabled(false); ui->pushButton_weigh->setEnabled(false); emit closeConnect(); }); } Widget::~Widget() { if(TimerGlbDly){ if(TimerGlbDly->isActive()) TimerGlbDly->stop(); delete TimerGlbDly; TimerGlbDly = NULL; } if(system_tray){ delete system_tray;