int TcpTask::recvCmd() { if(-1 == sock) return -1; char buff[128*1024]; int ret = TEMP_FAILURE_RETRY(::recv(sock,buff,sizeof(buff),MSG_NOSIGNAL)); if(-1 == ret && (errno == EAGAIN || errno == EWOULDBLOCK)) { //shoud retry return 0; } if(ret > 0) { t_NullCmd *ptNullCmd = (t_NullCmd *)buff; if(0 == ptNullCmd->cmd && CLIENT_NULL_PARA == ptNullCmd->para) { log.printLog("recv test signal"); if(!sendCmd((char *)ptNullCmd))//心跳测试 { return -1;//fd EOF } } else if(!msgParse((unsigned char*)buff,sizeof(buff))) { log.printLog("msgParse Error"); return 0; } } return -1;//ret==0 表明对方socket已关闭 }
void CTcpSocketBase::handler_read_body(const boost::system::error_code& error, std::size_t bytes_transferred,int offset) { if (!error) { int curr_offset = offset + (int)bytes_transferred; if (curr_offset < (int)msgRecv.bodylen()) { read_body(curr_offset); }else { msgParse(msgRecv.head(),msgRecv.alllen()); read_head(0); } }else { delete_self(error); } }
/** * \brief 从套接口中接受数据,并且拆包进行处理,在调用这个函数之前保证已经对套接口进行了轮询 * * \param needRecv 是否需要真正从套接口接受数据,false则不需要接收,只是处理缓冲中剩余的指令,true需要实际接收数据,然后才处理 * \return 接收是否成功,true表示接收成功,false表示接收失败,可能需要断开连接 */ bool zTCPTask::ListeningRecv(bool needRecv) { //Zebra::logger->debug("zTCPTask::ListeningRecv"); int retcode = 0; if (needRecv) { retcode = mSocket.recvToBuf_NoPoll(); } //struct timeval tv_2; if (-1 == retcode) { Zebra::logger->debug("zTCPTask::ListeningRecv -1"); Zebra::logger->error("zTCPTask::remoteport= %u localport = %u",mSocket.getPort(),mSocket.getLocalPort()); return false; } else { do { BYTE pstrCmd[zSocket::MAX_DATASIZE]; int nCmdLen = mSocket.recvToCmd_NoPoll(pstrCmd,sizeof(pstrCmd)); if (nCmdLen <= 0) //这里只是从缓冲取数据包,所以不会出错,没有数据直接返回 break; else { Cmd::t_NullCmd *pNullCmd = (Cmd::t_NullCmd *)pstrCmd; if (Cmd::CMD_NULL == pNullCmd->cmd && Cmd::PARA_NULL == pNullCmd->para) { //返回的测试指令,需要递减计数 //Zebra::logger->debug("服务端收到返回测试信号"); clearTick(); } else { msgParse(pNullCmd,nCmdLen); /* analysis.add(pNullCmd->cmd,pNullCmd->para,nCmdLen); // */ } } } while(true); } return true; }
/** * \brief 从套接口中接受数据,并且拆包进行处理,在调用这个函数之前保证已经对套接口进行了轮询 * * \param needRecv 是否需要真正从套接口接受数据,false则不需要接收,只是处理缓冲中剩余的指令,true需要实际接收数据,然后才处理 * \return 接收是否成功,true表示接收成功,false表示接收失败,可能需要断开连接 */ bool zTCPClientTask::ListeningRecv(bool needRecv) { //Zebra::logger->debug("zTCPClientTask::ListeningRecv"); if( pSocket == NULL ) return false; int retcode = 0; if (needRecv) { retcode = pSocket->recvToBuf_NoPoll(); } if (-1 == retcode) { Zebra::logger->error("zTCPClientTask::ListeningRecv"); return false; } else { do { BYTE pstrCmd[zSocket::MAX_DATASIZE]; int nCmdLen = pSocket->recvToCmd_NoPoll(pstrCmd,sizeof(pstrCmd)); if (nCmdLen <= 0) //这里只是从缓冲取数据包,所以不会出错,没有数据直接返回 break; else { Cmd::t_NullCmd *pNullCmd = (Cmd::t_NullCmd *)pstrCmd; if (Cmd::CMD_NULL == pNullCmd->cmd && Cmd::PARA_NULL == pNullCmd->para) { //Zebra::logger->debug("客户端收到测试信号"); if (!sendCmd(pstrCmd,nCmdLen)) { //发送指令失败,退出循环,结束线程 return false; } } else msgParse(pNullCmd,nCmdLen); } } while(true); } return true; }
/** * \brief 从套接口中接受数据,并且拆包进行处理,在调用这个函数之前保证已经对套接口进行了轮询 * * \param needRecv 是否需要真正从套接口接受数据,false则不需要接收,只是处理缓冲中剩余的指令,true需要实际接收数据,然后才处理 * \return 接收是否成功,true表示接收成功,false表示接收失败,可能需要断开连接 */ bool LTCPClientTask::ListeningRecv(bool needRecv) { int retcode = 0; if (needRecv) { retcode = pSocket->recvToBuf_NoPoll(); } if (-1 == retcode) { return false; } else { do { unsigned char pstrCmd[LSocket::MAX_DATASIZE]; int nCmdLen = pSocket->recvToCmd_NoPoll(pstrCmd, sizeof(pstrCmd)); if (nCmdLen <= 0) //这里只是从缓冲取数据包,所以不会出错,没有数据直接返回 break; else { #ifdef _NULCMD Cmd::t_NullCmd *ptNullCmd = (Cmd::t_NullCmd *)pstrCmd; if (Cmd::CMD_NULL == ptNullCmd->cmd && Cmd::PARA_NULL == ptNullCmd->para) { //Zebra::logger->debug("客户端收到测试信号"); if (!sendCmd(pstrCmd, nCmdLen)) { //发送指令失败,退出循环,结束线程 return false; } } else msgParse(ptNullCmd, nCmdLen); #endif } } while(true); } return true; }
//push cmd to queue void ClientConn::msg_parse(const void *cmd, const uint32_t len) { const Cmd::t_NullCmd *pNullCmd = (const Cmd::t_NullCmd *)cmd; msgParse(pNullCmd, len); }