void cria_socket_interno(int *vetorPortas) { FILE *fp; char readBuf[100]; char testeBuf[100]; umask(0); mknod(FIFO_FILE, S_IFIFO|0666, 0); relogio++; while(1) { strcpy(testeBuf, readBuf); fp = fopen(FIFO_FILE, "r"); fgets(readBuf, 80, fp); while(!strcmp(testeBuf,readBuf)) { fclose(fp); fp = fopen(FIFO_FILE, "r"); fgets(readBuf, 80, fp); } fclose(fp); printf("Sou interno e vou mandar essa mensagem para o externo %s\n", readBuf); cria_cliente(vetorPortas[0], readBuf); } }
/* Funcao que implementa a thread chat que escuta a mensagem do cliente e replica a todos os outros */ void chat(int temp_socket_cliente) /* Recebe como parametro o socket do cliente */ { int retorno; char temp_nome_cliente[30]; cliente *cliente; do /* Responsavel por validar o nome do cliente */ { retorno = recv(temp_socket_cliente,temp_nome_cliente,256,0); /* Recebe o nome informado pelo usuario */ if(retorno < 0){tratamento_de_erros(1);} /* Caso o retorno seja < 0 informa que nao foi possivel receber a informacao do cliente */ if(retorno == 0) /* Caso o retorno seja == 0 o cliente se desconectou, assim a thread eh finalizada */ { tratamento_de_erros(7); pthread_exit(NULL); } if(valida_nick(temp_nome_cliente) == 0) /* Chama a valida nick mandando o nome informado como parametro */ { retorno = send(temp_socket_cliente,"1\n",3,0); /* Caso o retorno seja zero ele manda 0 ao cliente dizendo que o nome informado jah existe cadastrado */ if(retorno < 0){tratamento_de_erros(2);} /* Caso o retorno for < 0 indica que nao foi possivel enviar o dado ao cliente */ continue; /* Chama continue para receber novamente o nick do usuario */ } else { retorno = send(temp_socket_cliente,"0\n",3,0); /* Caso for diferente de zero envia 0 dizendo que o nick foi validado pelo servidor*/ if(retorno < 0){tratamento_de_erros(2);} /* Caso o retorno for < 0 indica que nao foi possivel enviar o dado ao cliente */ break; /* Para de executar o do-while infinito para comecar a trocar mensagens com o cliente */ } }while(1); cliente = cria_cliente(temp_socket_cliente,temp_nome_cliente); /* Cria um novo cliente passando o socket e o nome do cliente*/ printf("Cliente (%s) conectou\n",cliente -> nome_cliente); /* Informa que o cliente atualmente esta validado no servidor */ do /* Responsavel por receber a mensagem do usuario e replicar para os outros clientes cadastrados */ { retorno = recv(cliente -> socket_cliente,cliente -> mensagem,256,0); /* Recebe a mensagem informada pelo usaurio */ if(retorno == 0) /* Se o retorno for zero indica que o cliente desconectou */ { printf("Cliente (%s) desconectou\n",cliente -> nome_cliente); /* Informa que cliente desconectou */ exclui_cliente(cliente); /* Exclui cliente da lista*/ pthread_exit(NULL); /* Desliga a thread */ } else if(retorno < 0) /* Caso o retorno for menor que zero informa que nao foi possivel receber a mensagem do cliente */ { tratamento_de_erros(1); } replica_mensagem(cliente); /* Replica aos outos clientes (Broadcast) a mensagem informada pelo cliente */ }while(1); }
void cria_socket_externo(int *vetorPortas) { int l; //Criando socket tcp para esperar conexoes if ((servSockExt = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP))<0){ perror("criacao socket interno falhou"); exit(1); } //printf("socket externo criado... %d\n", servSockExt); //Construindo endereco de conexao memset(&echoServAddrExt, 0, sizeof(echoServAddrExt)); echoServAddrExt.sin_family = AF_INET; echoServAddrExt.sin_addr.s_addr = htonl(INADDR_ANY); echoServAddrExt.sin_port = htons(vetorPortas[0]); //Bind ao endereco local if (bind(servSockExt, (struct sockaddr *)&echoServAddrExt, sizeof(echoServAddrExt))<0) { perror("bind externo falhou"); exit(1); } //printf("bind externo feito...\n"); //Fazendo listen if (listen(servSockExt,5)<0) { perror("listen externo falhou"); exit(1); } //printf("listen externo feito\n"); //Criacao da fila de mensagens fila *q_ext; q_ext = criaFila(); //Inicializa vetor de semaforos int z; for(z=0;z<NUM_PROCS;z++) { sem[z] = 1; } //Esperando conexoes com accept while(1) { inf *mens_ext; sprintf(echoBuffer,""); printf("esperando conexao externa\n"); clntLen = sizeof(echoClntAddrExt); if((clntSockExt = accept(servSockExt, (struct sockaddr *)&echoClntAddrExt, &clntLen))<0) { perror("accept externo falhou"); exit(1); } //printf("Tratando cliente %s\n", inet_ntoa(echoClntAddrExt.sin_addr)); recv(clntSockExt, echoBuffer, sizeof(echoBuffer), 0); sscanf(echoBuffer,"%d %d %d %d",&garfo,&idf,&msg,&rel); //printf("Sou externo e fiz o sscanf %d %d %d %d\n", garfo, idf, msg, rel); // printf("Sou externo e recebi essa msg do interno %s\n",echoBuffer); mens_ext = criarInfo(garfo, idf, msg, rel); sleep(1); // printf("Sou externo e criei o info %d %d %d %d\n",mens_ext->garfo,mens_ext->idf, mens_ext->msg, mens_ext->rel); //atualiza o relogio relogio++; rel = max(relogio, rel); mens_ext->rel = rel; //switch de tipo de msg if((mens_ext->msg == POP) || (mens_ext->msg == VOP)) { //Insere o nodo na fila de requisicoes insere(q_ext,mens_ext); // printf("Sou externo e vou inserir essa mensagem na fila %d %s %d\n", mens_ext->idf, mens_ext->msg, mens_ext->rel); //Broadcast para todos os outros sprintf(echoBuffer,""); sprintf(echoBuffer,"%d %d %d %d",garfo,idf,ACK,rel); // printf("Sou externo e vou fazer broadcast dessa mensagem %s\n",echoBuffer); sleep(1); int k=1; for(k = 1; k<NUM_PROCS; k++) { cria_cliente(vetorPortas[k],echoBuffer); } //Atualiza o relógio relogio++; rel = max(relogio, rel); mens_ext->rel=rel; //Teste de verificacao da fila // printf("----fila----\n"); // imprimeFila(q_ext); // printf("----fila----\n"); } else if(mens_ext->msg == REQP) { //Insere o nodo na fila de requisicoes mens_ext->msg = POP; insere(q_ext,mens_ext); printf("CHEGOU!\n"); //printf("Sou externo e vou inserir essa mensagem na fila %d %d %d\n", mens_ext->idf, mens_ext->msg, mens_ext->rel); //Broadcast para todos os outros sprintf(echoBuffer,""); sprintf(echoBuffer,"%d %d %d %d",garfo,idf,POP,rel); // printf("Sou externo e vou fazer broadcast dessa mensagem %s\n",echoBuffer); sleep(1); int k; for(k = 1; k<NUM_PROCS; k++) { cria_cliente(vetorPortas[k],echoBuffer); } //Atualiza o relogio relogio++; rel = max(relogio, rel); mens_ext->rel=rel; //Teste de verificacao da fila // printf("----fila----\n"); // imprimeFila(q_ext); // printf("----fila----\n"); } else if(mens_ext->msg == REQV){ //Insere o nodo na fila de requisicoes mens_ext->msg = VOP; insere(q_ext,mens_ext); //printf("Sou externo e vou inserir essa mensagem na fila %d %d %d\n", mens_ext->idf, mens_ext->msg, mens_ext->rel); //Broadcast para todos os outros sprintf(echoBuffer,""); sprintf(echoBuffer,"%d %d %d %d",garfo,idf,VOP,rel); // printf("Sou externo e vou fazer broadcast dessa mensagem %s\n",echoBuffer); sleep(1); int k; for(k = 1; k<NUM_PROCS; k++) { cria_cliente(vetorPortas[k],echoBuffer); } //Atualiza o relogio relogio++; rel = max(relogio, rel); mens_ext->rel=rel; //Teste de verificacao da fila // printf("----fila----\n"); // imprimeFila(q_ext); // printf("----fila----\n"); } else { printf("Recebi ACK!\n"); limpaFila(q_ext); }; } }