static void proc_pkt(unsigned char *pPkt, int pktLen, void *pUser) { //printf("pkt len: %d\n", pktLen); return; struct conn_data *_data = (struct conn_data*)pUser; struct cmd_header *pch = (struct cmd_header*)pPkt; _data->cmd = pch->cmd; _data->total_len = pch->len; switch(pch->cmd) { case 'e': if(pch->cls == 0) { sendResp(_data->hconn, 'e', pPkt + sizeof(struct cmd_header), pktLen - sizeof(struct cmd_header)); fprintf(stdout, "<<<"); } else fprintf(stdout, ">>>"); #define min(x, y) ((x)>(y)?(y):(x)) fwrite(pPkt + sizeof(struct cmd_header), 1, min(30, pktLen-sizeof(struct cmd_header)), stdout); fprintf(stdout, "\n"); break; case 'g': if(pch->cls == 0) { putFile(_data->hconn, (const char*)(pPkt + sizeof(struct cmd_header))); _data->cmd = _data->total_len = 0; } break; case 'p': if(pch->cls == 0) { struct ft_header *fth = (struct ft_header*)pPkt; _data->fp = fopen(fth->fn, "wb"); _data->total_len -= (pktLen - sizeof(struct ft_header)); if(_data->fp) { fwrite(fth+1, 1, pktLen - sizeof(struct ft_header), _data->fp); if(_data->total_len == 0) fclose(_data->fp); } } else { _data->total_len -= pktLen; if(_data->fp) { fwrite(pPkt, 1, pktLen, _data->fp); if(_data->total_len == 0) { fclose(_data->fp); _data->fp = NULL; } } } break; } }
void CSlaveTcpServer::proccessRequest(slave_tcp_msg_t* pstRequest, slave_socket_node_t & stSocket, int iOffset) { uint32_t uiType = 0; CSlaveServiceNode * pstNode = NULL; slave_service_run_data_msg_t *pRunData = NULL; if(NULL==pstRequest) { return; } //这里将socket和服务节点关联起来 socket全局节点不考虑上锁 人为约定只在接受消息流程中对socket进行改动 其他只是使用 //TODO 目前只是接收消息 没有调度进程 所以接收第一个消息时建立节点并且初始化 if(stSocket.usPid==0) { stSocket.usPid = pstRequest->uiPid; stSocket.usType = pstRequest->uiType; } uiType = pstRequest->uiType; g_slaveLog->log_info("recv msg(%u) from pid(%u) cdppid(%u)",pstRequest->uiMsgType, pstRequest->uiPid, pstRequest->uiCDPPid); g_vServiceList[uiType]->sLock.lock(); if(NULL==(pstNode=slaveFindServiceNode(pstRequest->uiType,pstRequest->uiCDPPid,pstRequest->uiStartTime))) { //建立新节点 pstNode = new CSlaveServiceNode(pstRequest->uiPid,pstRequest->uiType,pstRequest->uiCDPPid, pstRequest->uiStartTime,iOffset,g_pRunDataPool); slaveInsertServiceNode(pstNode); //更新心跳时间 pstNode->setAliveTime((uint32_t)time(NULL)); } //节点存在 else { g_slaveLog->log_info("update pid = %u CDPPid = %u alive time ", pstNode->getPid(),pstNode->getCDPPid()); //更新心跳时间 pstNode->setAliveTime((uint32_t)time(NULL)); //更新socket偏移量 不校验了 反正都是浪费CPU^_^ pstNode->setSocketOffset(iOffset); //更新pid和启动时间 pstNode->setPid(pstRequest->uiPid); pstNode->setStartTime(pstRequest->uiStartTime); //释放状态置假 pstNode->setReleaseFlagIsFalse(); //TODO 这里对TCP连接重新连接不考虑 在循环调度流程里处理 } //根据消息类型进行处理 switch(pstRequest->uiMsgType) { //心跳消息 刷新节点上时间 case HEARTBEAT_MSG: //返回心跳 pstRequest->uiPid=g_pSlaveGlobalConf->uiPid; pstRequest->uiType=CDP_SLAVE; pstRequest->uiStartTime=g_uiStartTime; sendResp(pstRequest, stSocket); break; //其他类型的消息处理 可能要入队 交给其他线程处理 比如数据库查询 case RUNDATA_MSG: if(pstRequest->uiDataLength!=sizeof(slave_service_run_data_msg_t)) { g_slaveLog->log_info("recv RUNDATA_MSG message, but length(%u) error!",pstRequest->uiDataLength); break; } //将运行数据保存到节点下 pRunData = (slave_service_run_data_msg_t *)pstRequest->data; pstNode->saveRunData(pRunData); //入队 TODO未来改用内存池可以直接处理 g_slaveLog->log_info("magic(%08x),pid=(%u);type=(%u);cdppid=(%u);msgtype=(%u);dataid(%u);outputdataid(%u);(%u,%u,%u,%u,%u,%u)\r\n", pstRequest->uiMagicWord, pstRequest->uiPid, pstRequest->uiType, pstRequest->uiCDPPid, pstRequest->uiMsgType, pRunData->uiDataId, pRunData->uiOutputDataId, pRunData->uiInputDataKByte, pRunData->uiOutputDataKByte, pRunData->uiInputItem, pRunData->uiOutputItem, pRunData->uiProcFaultTimes, pRunData->uiFormatError); break; default : g_slaveLog->log_info("unkown msg type %u ", pstRequest->uiMsgType); break; } g_vServiceList[uiType]->sLock.unlock(); //释放 g_pMsgPool->pushBlock((char *)pstRequest); g_slaveLog->log_info("proccess request end "); return ; }
void *trata_cliente(void *client_connection){ /*Variaveis exclusivas da thread*/ socklen_t ns; int l; char sendbuf[TAM_BUF], recvbuf[TAM_BUF]; int i=0, j=0, tid; int lidos, conectado = 1; printf("ns..."); paramCliente* par = (paramCliente*) (client_connection); ns = par->s; //tid = par->tid; tid = pthread_self(); struct sockaddr_in client = par->cli; printf("thr[%u]: Cliente se conectou com %d\n",(unsigned) tid,ns); while (conectado) { printf("thr[%u]: Aguardando mensagem do cliente\n", (unsigned)tid); if ( (lidos = recv(ns, recvbuf, sizeof(recvbuf), 0)) == -1) { perror("Recv()"); continue; } switch ( recvbuf[protocol_i]) { case cadastrar: printf("thr[%u]: O cliente na porta %d deseja cadastrar uma mensagem\n",(unsigned) tid,ntohs(client.sin_port)); pthread_mutex_lock(&mutex); if (mensagensCadastradas >= MAXMSGS) { pthread_mutex_unlock(&mutex); printf("thr[%u]: ERRO! Limite de mensagens cadastradas atingido. Enviando mensagem de erro ao cliente da porta %d\n",(unsigned)tid,ntohs(client.sin_port)); sendResp(sendbuf,ns,erro); break; } printf("thr[%u]: Cadastrando a mensagem\n",(unsigned)tid); strcpy(mensagensDB[mensagensCadastradas].nome,recvbuf+1); l = getNextString(recvbuf,1); strcpy(mensagensDB[mensagensCadastradas].msg,recvbuf+l); printf("thr[%u]: Cadastrado: Nome: %s, Mensagem: %s. Enviando Confirmacao ao cliente da porta %d\n",(unsigned)tid,mensagensDB[mensagensCadastradas].nome,mensagensDB[mensagensCadastradas].msg,ntohs(client.sin_port)); sendResp(sendbuf,ns,ack); mensagensCadastradas++; pthread_mutex_unlock(&mutex); break; case apagar: l = 1; int apagadas = 0; printf("thr[%u]: Cliente da porta %d deseja apagar mensagens de %s\n",(unsigned)tid,ntohs(client.sin_port),recvbuf+1); pthread_mutex_lock(&mutex); for (i =0; i < mensagensCadastradas;i++) { if (strcmp(recvbuf+1,mensagensDB[i].nome) == 0) { l = putBuff(sendbuf,l,mensagensDB[i].nome); l = putBuff(sendbuf,l,mensagensDB[i].msg); printf("thr[%u]: apagando mensagem de %s : %s...como pedido pelo cliete da porta %d\n",(unsigned) tid,mensagensDB[i].nome,mensagensDB[i].msg,ntohs(client.sin_port)); for (j = i+1; j<mensagensCadastradas;j++) //'puxa' as mensagens subsequentes, deletando a atual mensagensDB[j-1] = mensagensDB[j]; //não é eficiente, mas n vou criar uma lista ligada '-' mensagensCadastradas--; i--; apagadas++; } } pthread_mutex_unlock(&mutex); if (apagadas == 0) { sendResp(sendbuf,ns,vazio); } else { sendbuf[protocol_i] = ack; sendbuf[l] = '#'; //sinaliza sinal da lista de mensagens if (send(ns, sendbuf,l+1, 0) < 0) perror("Send()"); } break; case querSair: printf("thr[%u]: Cliente da porta %d deseja encerrar a conexao.\n",(unsigned) tid,ntohs(client.sin_port)); conectado = 0; break; case ler: printf("thr[%u]: Cliente da porta %d deseja ler as mensagens. Listando as mensagens cadastradas\n",(unsigned) tid,ntohs(client.sin_port)); pthread_mutex_lock(&mutex); if (mensagensCadastradas == 0) { pthread_mutex_unlock(&mutex); printf("thr[%u]: Nenhuma mensagem cadastrada. Enviando informacao ao cliente da porta %d.\n",(unsigned) tid,ntohs(client.sin_port)); sendResp(sendbuf,ns,vazio); break; } l = 1; for (i =0; i < mensagensCadastradas;i++) { l = putBuff(sendbuf,l,mensagensDB[i].nome); l = putBuff(sendbuf,l,mensagensDB[i].msg); printf("thr[%u]: Adicionando mensagem: Autor: %s Conteudo: %s, ao pacote para enviar ao cliente da porta %d\n",(unsigned) tid,mensagensDB[i].nome,mensagensDB[i].msg,ntohs(client.sin_port)); } pthread_mutex_unlock(&mutex); sendbuf[protocol_i] = ack; sendbuf[l] = '#'; //sinaliza final da lista de mensagens if (send(ns, sendbuf,l+1, 0) < 0) perror("Send()"); break; default: printf("thr[%u]: Comando de código %d desconhecido. Enviando resposta ao cliente da porta %d\n",(unsigned) tid,recvbuf[protocol_i],ntohs(client.sin_port)); sendResp(sendbuf,ns,invalido); break; } } pthread_exit(0); }