int testKeys() { int result, size, num_keys, num_keys_conv; short opcode, c_type; char *msg_str = NULL; struct message_t *msg; char *keys[] = {"ul2015", "SD", "teste", "123", NULL}; short sizes_conv[] = {htons(6), htons(2), htons(5), htons(3)}; printf("Módulo mensagem -> teste - Keys:"); msg = (struct message_t *) malloc(sizeof(struct message_t)); msg->opcode = OC_PUT; msg->c_type = CT_KEYS; msg->content.keys = (char **) malloc(5 * sizeof(char *)); msg->content.keys[0] = strdup("ul2015"); msg->content.keys[1] = strdup("SD"); msg->content.keys[2] = strdup("teste"); msg->content.keys[3] = strdup("123"); msg->content.keys[4] = NULL; size = message_to_buffer(msg, &msg_str); opcode = htons(msg->opcode); c_type = htons(msg->c_type); num_keys = 4; num_keys_conv = htonl(num_keys); result = memcmp(msg_str, &opcode, 2) == 0 && memcmp(msg_str + 2, &c_type, 2) == 0 && memcmp(msg_str + 4, &num_keys_conv, 4) == 0 && memcmp(msg_str + 8, &sizes_conv[0], 2) == 0 && memcmp(msg_str + 10, keys[0], strlen(keys[0])) == 0 && memcmp(msg_str + 16, &sizes_conv[1], 2) == 0 && memcmp(msg_str + 18, keys[1], strlen(keys[1])) == 0 && memcmp(msg_str + 20, &sizes_conv[2], 2) == 0 && memcmp(msg_str + 22, keys[2], strlen(keys[2])) == 0 && memcmp(msg_str + 27, &sizes_conv[3], 2) == 0 && memcmp(msg_str + 29, keys[3], strlen(keys[3])) == 0; free_message(msg); msg = buffer_to_message(msg_str, size); result = result && msg->opcode == OC_PUT && msg->c_type == CT_KEYS && strcmp(msg->content.keys[0], keys[0]) == 0 && strcmp(msg->content.keys[1], keys[1]) == 0 && strcmp(msg->content.keys[2], keys[2]) == 0 && strcmp(msg->content.keys[3], keys[3]) == 0 && msg->content.keys[4] == NULL; free(msg_str); //print_message(msg); free_message(msg); printf(" %s\n", result ? "passou" : "não passou"); return result; }
int testInvalida() { int result; char *msg_lixada1 = "1234 50 abcederdfasdasfsdfafadgadgagadgadhgdfhsghsshg"; struct message_t *msg; printf("Módulo mensagem -> teste - Inválida:"); msg = buffer_to_message(msg_lixada1, strlen(msg_lixada1)+1); result = (msg == NULL); printf(" %s\n", result ? "passou" : "não passou"); return result; }
int testValue() { int result, size, datasize, datasize_conv; short opcode, c_type; char *msg_str = NULL; char *datastr; struct message_t *msg; printf("Módulo mensagem -> teste - Value:"); msg = (struct message_t *) malloc(sizeof(struct message_t)); msg->opcode = OC_PUT; msg->c_type = CT_VALUE; datastr = strdup("abc"); msg->content.data = data_create2(strlen("abc") + 1, datastr); size = message_to_buffer(msg, &msg_str); opcode = htons(msg->opcode); c_type = htons(msg->c_type); datasize = msg->content.data->datasize; datasize_conv = htonl(datasize); char comp_data[datasize]; memcpy(comp_data, msg_str + 8, datasize); result = memcmp(msg_str, &opcode, 2) == 0 && memcmp(msg_str + 2, &c_type, 2) == 0 && memcmp(msg_str + 4, &datasize_conv, 4) == 0 && memcmp(msg_str + 8, &comp_data, datasize) == 0; free_message(msg); msg = buffer_to_message(msg_str, size); result = result && msg->opcode == OC_PUT && msg->c_type == CT_VALUE && msg->content.data->datasize == strlen("abc")+1 && strcmp(msg->content.data->data,"abc") == 0; free(msg_str); free(datastr); //print_message(msg); free_message(msg); printf(" %s\n", result ? "passou" : "não passou"); return result; }
int testKey() { int result, size, keysize; short keysize_conv, opcode, c_type; char *msg_str = NULL; struct message_t *msg; printf("Modulo mensagem -> teste - Key:"); msg = (struct message_t *)malloc(sizeof(struct message_t)); msg->opcode = OC_PUT; msg->c_type = CT_KEY; msg->content.key = strdup("abcdef"); size = message_to_buffer(msg,&msg_str); opcode = htons(msg->opcode); c_type = htons(msg->c_type); keysize = strlen(msg->content.key); keysize_conv = htons((short) keysize); char comp_key[keysize]; memcpy(comp_key, msg_str + 6, keysize); result = memcmp(msg_str, &opcode, 2) == 0 && memcmp(msg_str + 2, &c_type, 2) == 0 && memcmp(msg_str + 4, &keysize_conv, 2) == 0 && memcmp(msg_str + 6, &comp_key, keysize) == 0; free_message(msg); msg = buffer_to_message(msg_str, size); result = result && msg->opcode == OC_PUT && msg->c_type == CT_KEY && strcmp(msg->content.key, "abcdef") == 0; free(msg_str); //print_message(msg); free_message(msg); printf(" %s\n", result ? "passou" : "não passou"); return result; }
int testResult() { int result, size, res; short opcode, c_type; char *msg_str = NULL; struct message_t *msg; printf("Módulo mensagem -> teste - Result:"); msg = (struct message_t *) malloc(sizeof(struct message_t)); msg->opcode = OC_PUT; msg->c_type = CT_RESULT; msg->content.result = 1; size = message_to_buffer(msg, &msg_str); opcode = htons(msg->opcode); c_type = htons(msg->c_type); res = htonl(msg->content.result); result = memcmp(msg_str, &opcode, 2) == 0 && memcmp(msg_str + 2, &c_type, 2) == 0 && memcmp(msg_str + 4, &res, 4) == 0; free_message(msg); msg = buffer_to_message(msg_str, size); result = result && msg->opcode == OC_PUT && msg->c_type == CT_RESULT && msg->content.result == 1; free(msg_str); //print_message(msg); free_message(msg); printf(" %s\n", result ? "passou":"não passou"); return result; }
int testEntry() { int result, size, keysize, datasize, datasize_conv; short opcode, c_type, keysize_conv; char *msg_str = NULL; char *datastr = strdup("abc"); struct message_t *msg; struct data_t *d; printf("Módulo mensagem -> teste - Entry"); d = data_create2(strlen(datastr) + 1, datastr); msg = (struct message_t *) malloc(sizeof(struct message_t)); msg->opcode = OC_PUT; msg->c_type = CT_ENTRY; msg->content.entry = entry_create(datastr, d); data_destroy(d); size = message_to_buffer(msg, &msg_str); opcode = htons(msg->opcode); c_type = htons(msg->c_type); keysize = strlen(msg->content.entry->key); keysize_conv = htons(keysize); char comp_key[keysize]; memcpy(comp_key, msg_str + 6, keysize); datasize = msg->content.entry->value->datasize; datasize_conv = htonl(datasize); char comp_data[datasize]; memcpy(comp_data, msg_str + 4 + 2 + keysize + 4, datasize); result = memcmp(msg_str, &opcode, 2) == 0 && memcmp(msg_str + 2, &c_type, 2) == 0 && memcmp(msg_str + 4, &keysize_conv, 2) == 0 && memcmp(msg_str + 6, &comp_key, keysize) == 0 && memcmp(msg_str + 6 + keysize, &datasize_conv, 4) == 0 && memcmp(msg_str + 6 + keysize + 4, &comp_data, datasize) == 0; free_message(msg); msg = buffer_to_message(msg_str, size); result = result && msg->opcode == OC_PUT && msg->c_type == CT_ENTRY && strcmp(msg->content.entry->key, datastr) == 0 && msg->content.entry->value->datasize == strlen(datastr) + 1 && strcmp(msg->content.entry->value->data, datastr) == 0; free(msg_str); free(datastr); //print_message(msg); free_message(msg); printf(" %s\n", result ? "passou" : "não passou"); return result; }
int main(int argc, char **argv){ int sockfd, connsockfd, cont = 2, i, socketsecundario; struct sockaddr_in server, client; struct pollfd desc_set[MAX_CLIENT];//Definido para 10 utilizadores em max_client struct table_t *table=(struct table_t*)malloc(sizeof(struct table_t)); char *terminal = malloc(sizeof(char)); int nbytes, msg_size, count; socklen_t size_client; // Verifica se foi passado algum argumento if (argc != 3 && argc != 5){ printf("Servidor sem replicação: Uso: ./table_server <porto_servidor> <size_table>\n"); printf("Servidor com replicação: Uso: ./table_server <porto_servidor> <porto2_servidor> <size_table> <ip_serverSecundario>\n"); return -1; } //Ligar servidor replicado if(argc == 5){ socketsecundario = ligarBackup(argv[4], argv[2]); } // Cria socket TCP if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror("Erro ao criar socket"); return -1; } // Preenche estrutura server para bind server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = htons(atoi(argv[1])); // Faz bind if (bind(sockfd, (struct sockaddr *) &server, sizeof(server)) < 0){ perror("Erro ao fazer bind"); close(sockfd); return -1; }; // Faz listen if(listen(sockfd, 20) < 0){ perror("Erro ao executar listen"); close(sockfd); return -1; }; //cria table table=table_skel_init(atoi(argv[2])); desc_set[0].fd=fileno(stdin); desc_set[0].events=POLLIN; desc_set[0].revents=0; desc_set[1].fd=sockfd; //Listen socket desc_set[1].events=POLLIN; desc_set[1].revents=0; for(i=2; i< MAX_CLIENT; i++){ desc_set[i].fd=-1; desc_set[i].events=0; desc_set[i].revents=0; } printf("**Estrutura de dados criada**\n**Servidor 'a espera de dados**\n"); //Espera por dados nos sockets abertos while(poll(desc_set, MAX_CLIENT, -1) >= 0){ /*Tentativa de nova ligacao*/ if(desc_set[1].revents & POLLIN){ connsockfd = accept( desc_set[1].fd, ( struct sockaddr * )&client, &size_client); //adiciona connsockfd a desc_set desc_set[cont].fd=connsockfd; desc_set[cont].events=POLLIN; cont++; } /*Testar se ha algum evento extra por exemplo o pedido de informaçao do conteudo actual do server*/ if(desc_set[0].revents & POLLIN){ fgets(terminal, MAX_MSG, stdin); terminal=strtok(terminal, "\n"); if(strcmp(terminal, "print")== 0){ int conta=0; char **tabela; tabela = table_get_keys(table); printf("A tabela actual e': \n"); while(tabela[conta]!=NULL){ printf("Key na posição [%d]: %s", conta, tabela[conta]); conta++; } }else{ printf("erro! escreva print para apresentar o conteudo actual do server\n"); } } for(i=2; i<cont; i++){ if (desc_set[i].revents & POLLIN) { // Lê string enviada pelo cliente do socket referente a conexão if((nbytes = read(desc_set[i].fd,&msg_size,sizeof(int))) <= 0){ //perror("Erro ao receber dados do cliente1"); close(desc_set[i].fd); continue; } msg_size=ntohl(msg_size); char *msg_buf=(char *)malloc(msg_size+1); if((nbytes = read_all(desc_set[i].fd,msg_buf,msg_size)) < 0){ perror("Erro ao receber dados do cliente2"); close(desc_set[i].fd); continue; } struct message_t *msg_recebida = buffer_to_message(msg_buf, msg_size); free(msg_buf); if(argc==5){ //actualizar o backup de acordo com o tipo de escrita if((msg_recebida->opcode)==OC_PUT){ if(actualizarBackup(msg_recebida->content.entry->key, msg_recebida->content.entry->value,1)==-1) perror("Erro a receber OK do servidor secundario\n"); } if((msg_recebida->opcode)==OC_COND_PUT){ if(actualizarBackup(msg_recebida->content.entry->key, msg_recebida->content.entry->value,1)==-1) perror("Erro a receber OK do servidor secundario\n"); } if((msg_recebida->opcode)==OC_DEL){ if(actualizarBackup(msg_recebida->content.key, msg_recebida->content.entry->value,0)==-1) perror("Erro a receber OK do servidor secundario\n"); } } int res=invoke(msg_recebida); //Envia resposta ao cliente depois de converter para formato de rede msg_size = message_to_buffer(msg_recebida,&msg_buf); msg_size = htonl(msg_size); free_message(msg_recebida); // Envia tamanho do buffer ao cliente através do socket referente a conexão if((nbytes = write(desc_set[i].fd,(char*)&msg_size,sizeof(int))) != sizeof(int)){ perror("Erro ao enviar resposta ao cliente"); close(desc_set[i].fd); continue; } msg_size=ntohl(msg_size); if((nbytes = write_all(desc_set[i].fd,msg_buf,msg_size) != msg_size)){ perror("Erro ao enviar resposta ao cliente"); close(desc_set[i].fd); continue; } //Verifica-se se a ligaçao foi desligada if (desc_set[i].revents & POLLHUP){ close(desc_set[i].fd); desc_set[i].fd = -1; desc_set[i].events = 0; } } } } //elimina table table_skel_destroy(); // Fecha socket close(connsockfd); close(sockfd); return 0; }