Ejemplo n.º 1
0
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;
	}
}
Ejemplo n.º 2
0
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);
}