/* Código do cliente do trabalho de Redes 2 "Artilharia UDP" Implementado por Leandro Rodrigues e Matheus Rotondano */ #include #include #include #include #include #include #include #include #include #define MAXNOMELOCAL 32 #define MSGSIZ 16 /* Struct para utilizar o time.h */ typedef struct tm tm; /* Variaveis globais que servem para, respectivamente: - Controlar o loop que faz o cliente enviar mensagens até que um ctrl+C seja encontrado. - Contar o total de mensagens enviadas pelo cliente. */ static int executa = 1; unsigned int msgsEnviadas = 0; /* Arquivo do log do cliente */ FILE *logFile; /* Headers das funções criadas */ void intHandler(int dummy); void finalizarCliente(); void initLog(FILE * log); void escreveLog(FILE * log, char * s); main(int argc, char *argv[]) { int sockdescr; int numbytesrecv; struct sockaddr_in sa; struct hostent *hp; char *host; char maquinaId[MAXNOMELOCAL]; int currTest = 1; //Contador do numero atual da mensagem int numTestes; //Numero total de mensagens que esse cliente manda char msg[MSGSIZ+1]; unsigned int i; /* Mensagem de erro caso o usuario esteja executando o programa de modo errado */ if(argc != 5) { puts("Uso correto: cliente "); exit(1); } /* Variaveis para pegar o horario do computador para colocar no log */ time_t tempo_atual; tm *tempo; time(&tempo_atual); tempo = localtime(&tempo_atual); strcpy(maquinaId, argv[1]); /* É criado um diretório chamado logClient onde todos os logs de execução do cliente são salvos. Sempre que o cliente é iniciado, um arquivo chamado "logClient .txt" é criado dentro desse diretório. */ char logPath[64]; mkdir("logClient", 0777); sprintf(logPath, "logClient/logClient %2.2d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d.txt", tempo->tm_mday, tempo->tm_mon, tempo->tm_year+1900, tempo->tm_hour, tempo->tm_min, tempo->tm_sec); logFile = fopen(logPath, "wr+"); fprintf(logFile, "Log criado em %2.2d/%2.2d/%2.2d %2.2dh:%2.2dm:%2.2ds\n", tempo->tm_mday, tempo->tm_mon, tempo->tm_year+1900, tempo->tm_hour, tempo->tm_min, tempo->tm_sec); fprintf(logFile, "Comecei a executar o cliente %s\n\n", maquinaId); host = argv[2]; numTestes = atoi(argv[4]); memset(msg, 0, MSGSIZ+1); /* O programa é abortado caso o cliente nao consiga obter o IP do servidor */ if((hp = gethostbyname(host)) == NULL){ fprintf(logFile, "Nao consegui obter endereco IP do servidor.\n"); fprintf(logFile, "\nLog finalizado em %2.2d/%2.2d/%2.2d %2.2dh:%2.2dm:%2.2ds\n", tempo->tm_mday, tempo->tm_mon, tempo->tm_year+1900, tempo->tm_hour, tempo->tm_min, tempo->tm_sec); fclose(logFile); exit(1); } bcopy((char *)hp->h_addr, (char *)&sa.sin_addr, hp->h_length); sa.sin_family = hp->h_addrtype; sa.sin_port = htons(atoi(argv[3])); /* O programa é abortado caso o cliente nao consiga abrir o socket */ if((sockdescr=socket(hp->h_addrtype, SOCK_DGRAM, 0)) < 0) { fprintf(logFile, "Nao consegui abrir o socket.\n"); fprintf(logFile, "\nLog finalizado em %2.2d/%2.2d/%2.2d %2.2dh:%2.2dm:%2.2ds\n", tempo->tm_mday, tempo->tm_mon, tempo->tm_year+1900, tempo->tm_hour, tempo->tm_min, tempo->tm_sec); fclose(logFile); exit(1); } /* Envia x mensagens onde x é o valor que o usuário passou na linha de comando. */ if (numTestes >= 0) { while (currTest <= numTestes) { sprintf(msg,"%s %d", maquinaId, currTest); /* O programa é abortado caso o cliente nao consiga enviar os dados */ if(sendto(sockdescr, msg, strlen(msg)+1, 0, (struct sockaddr *) &sa, sizeof sa) != strlen(msg)+1) { fprintf(logFile, "Nao consegui mandar os dados\n"); fprintf(logFile, "\nLog finalizado em %2.2d/%2.2d/%2.2d %2.2dh:%2.2dm:%2.2ds\n", tempo->tm_mday, tempo->tm_mon, tempo->tm_year+1900, tempo->tm_hour, tempo->tm_min, tempo->tm_sec); fclose(logFile); exit(1); } else { memset(msg, 0, MSGSIZ+1); ++currTest; ++msgsEnviadas; } } } /* Se o usuario falou que queria enviar -1 mensagens, o cliente envia mensagens continuamente até o usuario entrar com ctrl+C */ else { signal(SIGINT, intHandler); while (executa) { sprintf(msg,"%s %d", maquinaId, currTest); if(sendto(sockdescr, msg, strlen(msg)+1, 0, (struct sockaddr *) &sa, sizeof sa) != strlen(msg)+1) { fprintf(logFile, "Nao consegui mandar os dados.\n"); fprintf(logFile, "\nLog finalizado em %2.2d/%2.2d/%2.2d %2.2dh:%2.2dm:%2.2ds\n", tempo->tm_mday, tempo->tm_mon, tempo->tm_year+1900, tempo->tm_hour, tempo->tm_min, tempo->tm_sec); fclose(logFile); exit(1); } else { memset(msg, 0, MSGSIZ+1); ++currTest; ++msgsEnviadas; } } printf("\nCtrl + C, encerrando execucao do clietnte.\n"); fprintf(logFile, "\nCtrl + C, encerrando execucao do clietnte.\n"); } finalizarCliente(sockdescr, logFile, msg, host); exit(0); } /* Função que encerra o programa quando ctrl+C é encontrado. */ void intHandler(int dummy) { executa = 0; } /* Função que finaliza o cliente. */ void finalizarCliente(int sockdescr, FILE *logFile, char msg[], char *host){ time_t tempo_atual; tm *tempo; time(&tempo_atual); tempo = localtime(&tempo_atual); close(sockdescr); memset(msg, 0, MSGSIZ+1); fprintf(logFile, "Terminei de executar o cliente com sucesso.\n"); fprintf(logFile, "%d mensagens foram enviadas para o servidor %s\n", msgsEnviadas, host); fprintf(logFile, "\nLog finalizado em %2.2d/%2.2d/%2.2d %2.2dh:%2.2dm:%2.2ds\n", tempo->tm_mday, tempo->tm_mon, tempo->tm_year+1900, tempo->tm_hour, tempo->tm_min, tempo->tm_sec); fclose(logFile); exit(0); }