void la_wait (t_nombre_semaforo identificador_semaforo){ if(status_check() != EXECUTING) return; void * buffer = NULL, *response_buffer = calloc(1,sizeof(char)); int buffer_index = 0, identificador_semaforo_length = (int) strlen(identificador_semaforo); char operation = SEMAPHORE_ID, action = WAIT_ID; // asprintf(&buffer, "%d%d%04d%s", atoi(SEMAPHORE_ID), atoi(WAIT_ID), strlen(identificador_semaforo), identificador_semaforo); serialize_data(&operation, sizeof(char), &buffer, &buffer_index); serialize_data(&action, sizeof(char), &buffer, &buffer_index); serialize_data(&identificador_semaforo_length, sizeof(int), &buffer, &buffer_index); serialize_data(identificador_semaforo, (size_t) identificador_semaforo_length, &buffer, &buffer_index); if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) { log_error(cpu_log, "wait(%s) failed", identificador_semaforo); return; } status_update(WAITING); log_info(cpu_log, "Starting wait"); //me quedo esperando activamente a que kernel me responda // recv(kernelSocketClient, response_buffer, sizeof(char), 0); //kernel_response debería ser '0' // log_info(cpu_log, "Finished wait"); free(buffer); free(response_buffer); }
t_valor_variable obtenerValorCompartida(t_nombre_compartida variable){ if(status_check() != EXECUTING) return ERROR; //5 + 0 + nameSize + name (1+1+4+nameSize bytes) void* buffer = NULL; int value = 0, variable_name_length = (int) strlen(variable), buffer_index = 0; char operation = SHARED_VAR_ID, action = GET_VAR; // asprintf(&buffer, "%d%d%04d%s", atoi(SHARED_VAR_ID), atoi(GET_VAR), strlen(variable), variable); serialize_data(&operation, sizeof(char), &buffer, &buffer_index); serialize_data(&action, sizeof(char), &buffer, &buffer_index); serialize_data(&variable_name_length, sizeof(int), &buffer, &buffer_index); serialize_data(variable, (size_t) variable_name_length, &buffer, &buffer_index); if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) { log_error(cpu_log, "send of obtener variable compartida of %s failed", variable); free(buffer); return ERROR; } free(buffer); buffer = calloc(1, sizeof(int)); if(recv(kernelSocketClient, buffer, sizeof(int), 0) <= 0) { log_error(cpu_log, "recv of obtener variable compartida failed"); return ERROR; } int deserialize_index = 0; deserialize_data(&value, sizeof(int), buffer, &deserialize_index); log_info(cpu_log, "recv value %d of obtener variable %s", value, variable); free(buffer); return value; }
int get_instruction_line(t_list *instruction_addresses_list, void ** instruction_line) { void * recv_bytes_buffer = NULL; int buffer_index = 0; while(list_size(instruction_addresses_list) > 0) { logical_addr * element = list_get(instruction_addresses_list, 0); // sprintf(aux_buffer, "%d%04d%04d%04d", PEDIDO_BYTES, element->page_number, element->offset, element->tamanio); void * aux_buffer = NULL; int aux_buffer_index = 0; char operacion = PEDIDO_BYTES; serialize_data(&operacion, sizeof(char), &aux_buffer,&aux_buffer_index); serialize_data(&element->page_number, sizeof(int), &aux_buffer, &aux_buffer_index); serialize_data(&element->offset, sizeof(int), &aux_buffer, &aux_buffer_index); serialize_data(&element->tamanio, sizeof(int), &aux_buffer, &aux_buffer_index); log_info(cpu_log, "Fetching for (%d,%d,%d) in UMC", element->page_number, element->offset, element->tamanio); //Send bytes request to UMC if( send(umcSocketClient, aux_buffer, aux_buffer_index, 0) < 0) { puts("Last Fetch failed"); return ERROR; } //Recv response recv_bytes_buffer = calloc(1, (size_t) element->tamanio); if(recv_bytes_buffer == NULL) { log_error(cpu_log, "get_instruction_line recv_bytes_buffer mem alloc failed"); return ERROR; } if(check_umc_response(recv_umc_response_status()) != SUCCESS) { return ERROR; } if( recv(umcSocketClient , recv_bytes_buffer , (size_t ) element->tamanio , 0) <= 0) { log_error(cpu_log, "UMC bytes recv failed"); return ERROR; } log_info(cpu_log, "Bytes Received: %s", (char*) recv_bytes_buffer); *instruction_line = realloc(*instruction_line, (size_t) buffer_index+element->tamanio); memcpy(*instruction_line+buffer_index, recv_bytes_buffer, (size_t) element->tamanio); buffer_index += element->tamanio; free(recv_bytes_buffer); list_remove_and_destroy_element(instruction_addresses_list, 0, free); } *instruction_line = realloc(*instruction_line, (size_t) (sizeof(char) + buffer_index)); * (char*)(*instruction_line+buffer_index) = '\0'; return SUCCESS; }
int change_active_process() { //send actual process pid void * buffer = NULL; // asprintf(&buffer, "%d%04d", CAMBIO_PROCESO_ACTIVO, actual_pcb->pid); int buffer_index = 0; char operacion = CAMBIO_PROCESO_ACTIVO; serialize_data(&operacion, sizeof(char), &buffer, &buffer_index); serialize_data(&actual_pcb->pid, sizeof(int), &buffer, &buffer_index); if( send(umcSocketClient , buffer, (size_t) buffer_index, 0) < 0) { log_error(cpu_log, "Send pid %d to UMC failed", actual_pcb->pid); return ERROR; } free(buffer); log_info(cpu_log, "Changed active process to current pid : %d", actual_pcb->pid); return SUCCESS; }
void imprimir(t_valor_variable valor) { if(status_check() != EXECUTING) return; void * buffer = NULL; int buffer_index = 0; char operation = IMPRIMIR_ID; // asprintf(&buffer, "%d%04d", atoi(IMPRIMIR_ID), valor); serialize_data(&operation , sizeof(char), &buffer, &buffer_index); serialize_data(&valor, sizeof(int), &buffer, &buffer_index); if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) { log_error(cpu_log, "imprimir value %d send to KERNEL failed", valor); return ; } log_info(cpu_log, "imprimir value %d sent to KERNEL"); free(buffer); }
t_valor_variable dereferenciar(t_posicion direccion_variable) { if(status_check() != EXECUTING) return ERROR; //Hacemos el request a la UMC con el codigo 2 t_list *pedidos = NULL; construir_operaciones_lectura(&pedidos, direccion_variable); void * variable_buffer = calloc(1, ANSISOP_VAR_SIZE), *umc_request_buffer = NULL; int variable_buffer_index = 0; char response_status; logical_addr * current_address = NULL; while(list_size(pedidos) > 0) { current_address = list_remove(pedidos, 0); // asprintf(&umc_request_buffer, "3%04d%04d%04d", current_address->page_number, // current_address->offset, current_address->tamanio); int umc_request_buffer_index = 0; char operation = PEDIDO_BYTES; serialize_data(&operation, sizeof(char), &umc_request_buffer, &umc_request_buffer_index); serialize_data(¤t_address->page_number, sizeof(int), &umc_request_buffer, &umc_request_buffer_index); serialize_data(¤t_address->offset, sizeof(int), &umc_request_buffer, &umc_request_buffer_index); serialize_data(¤t_address->tamanio, sizeof(int), &umc_request_buffer, &umc_request_buffer_index); log_info(cpu_log, "sending request : op:%c (%d,%d,%d) for direccion variable %d",operation, current_address->page_number, current_address->offset, current_address->tamanio, direccion_variable); // log_info(cpu_log, "sending request : %s for direccion variable %d", &umc_request_buffer, direccion_variable); if( send(umcSocketClient, umc_request_buffer, (size_t) umc_request_buffer_index, 0) < 0) { log_error(cpu_log, "UMC expected addr send failed"); return ERROR; } if(check_umc_response(recv_umc_response_status()) != SUCCESS) { return ERROR; } if( recv(umcSocketClient , ((char*) variable_buffer) + variable_buffer_index , (size_t) current_address->tamanio, 0) <= 0) { log_error(cpu_log, "UMC response recv failed"); break; } variable_buffer_index += current_address->tamanio; } free(umc_request_buffer); log_info(cpu_log, "Valor variable obtained : %d", *(int*)variable_buffer); return (t_valor_variable) *(t_valor_variable*)variable_buffer; }
void la_signal (t_nombre_semaforo identificador_semaforo){ if(status_check() != EXECUTING) return; void * buffer = NULL; int buffer_index = 0, identificador_semaforo_length = (int) strlen(identificador_semaforo); char operation = SEMAPHORE_ID, action = SIGNAL_ID; // asprintf(&buffer, "%d%d%04d%s", atoi(SEMAPHORE_ID), atoi(SIGNAL_ID), strlen(identificador_semaforo), identificador_semaforo); serialize_data(&operation, sizeof(char), &buffer, &buffer_index); serialize_data(&action, sizeof(char), &buffer, &buffer_index); serialize_data(&identificador_semaforo_length, sizeof(int), &buffer, &buffer_index); serialize_data(identificador_semaforo, identificador_semaforo_length, &buffer, &buffer_index); if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) { log_error(cpu_log, "signal(%s) failed", identificador_semaforo); return; } }
void catalog_object::serialize() { cs_stream stream(p_object, cs_stream::mode_write); int magic = get_magic(); stream.write(&magic, sizeof(int)); serialize_data(stream); stream.commit(); if (p_object == XNULL) { p_object = stream.get_xptr(); }; }
void armar_pedidos_escritura(t_list ** pedidos, t_list *direcciones, int valor) { t_nodo_send * nodo = NULL; int index = 0, indice_copiado = 0; logical_addr * address = NULL; *pedidos = list_create(); char operation = ALMACENAMIENTO_BYTES; while(list_size(direcciones) > 0) { address = list_remove(direcciones, index); nodo = calloc(1, sizeof(t_nodo_send)); serialize_data(&operation, sizeof(char), &nodo->data ,&nodo->data_length); serialize_data(&address->page_number, sizeof(int), &nodo->data ,&nodo->data_length); serialize_data(&address->offset, sizeof(int), &nodo->data ,&nodo->data_length); serialize_data(&address->tamanio, sizeof(int), &nodo->data ,&nodo->data_length); serialize_data( ((char*) (&valor)) + indice_copiado, (size_t) address->tamanio, &nodo->data, &nodo->data_length); indice_copiado += address->tamanio; list_add(*pedidos,nodo); } }
void imprimirTexto(char* texto) { if(status_check() != EXECUTING) return; void * buffer = NULL; int texto_len = (int) strlen(texto), buffer_index = 0; char operation = IMPRIMIR_TEXTO_ID; // asprintf(&buffer, "%d%04d%s", atoi(IMPRIMIR_TEXTO_ID), texto_len, texto); serialize_data(&operation, sizeof(char), &buffer, &buffer_index); serialize_data(&texto_len, sizeof(int), &buffer, &buffer_index); serialize_data(texto, (size_t) texto_len, &buffer, &buffer_index); if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) { log_error(cpu_log, "imprimirTexto with texto : %s , send failed", texto); return; } log_info(cpu_log, "imprimirTexto with texto : %s , sent to KERNEL", texto); free(buffer); }
int serialize_kvp(lua_sandbox* lsb, serialization_data* data, size_t parent) { int kindex = -2, vindex = -1; if (ignore_value_type(lsb, data, vindex)) return 0; int result = serialize_data(lsb, kindex, &lsb->m_output); if (result != 0) return result; size_t pos = data->m_keys.m_pos; if (dynamic_snprintf(&data->m_keys, "%s[%s]", data->m_keys.m_data + parent, lsb->m_output.m_data)) { return 1; } fprintf(data->m_fh, "%s = ", data->m_keys.m_data + pos); if (lua_type(lsb->m_lua, vindex) == LUA_TTABLE) { const void* ptr = lua_topointer(lsb->m_lua, vindex); table_ref* seen = find_table_ref(&data->m_tables, ptr); if (seen == NULL) { seen = add_table_ref(&data->m_tables, ptr, pos); if (seen != NULL) { data->m_keys.m_pos += 1; fprintf(data->m_fh, "{}\n"); result = serialize_table(lsb, data, pos); } else { snprintf(lsb->m_error_message, ERROR_SIZE, "preserve table out of memory"); return 1; } } else { data->m_keys.m_pos = pos; fprintf(data->m_fh, "%s\n", data->m_keys.m_data + seen->m_name_pos); } } else { data->m_keys.m_pos = pos; result = serialize_data(lsb, vindex, &lsb->m_output); if (result == 0) { fprintf(data->m_fh, "%s\n", lsb->m_output.m_data); } } return result; }
t_valor_variable asignarValorCompartida(t_nombre_compartida variable, t_valor_variable valor){ if(status_check() != EXECUTING) return ERROR; //5 + 1 + nameSize + name + value (1+1+4+nameSize+4 bytes) void* buffer = NULL; int buffer_index = 0, variable_length = (int) strlen(variable); char operation = SHARED_VAR_ID, action = SET_VAR; // asprintf(&buffer, "%d%d%04d%s%04d", atoi(SHARED_VAR_ID), atoi(SET_VAR), strlen(variable), variable, valor); serialize_data(&operation, sizeof(char), &buffer, &buffer_index); serialize_data(&action, sizeof(char), &buffer, &buffer_index); serialize_data(&variable_length, sizeof(int), &buffer, &buffer_index); serialize_data(variable, (size_t) variable_length, &buffer, &buffer_index); serialize_data(&valor, sizeof(int), &buffer, &buffer_index); if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) { log_error(cpu_log, "set value of %s failed", variable); return ERROR; } log_info(cpu_log, "asignarValorCompartida of %s with value %d was successful", variable, valor); free(buffer); return valor; }
void entradaSalida(t_nombre_dispositivo dispositivo, int tiempo) { if(status_check() != EXECUTING) return; //cambio el estado del pcb status_update(BLOCKED); //3+ ioNameSize + ioName + io_units (1+4+ioNameSize+4 bytes) void * buffer = NULL; char operation = ENTRADA_SALIDA_ID; int dispositivo_length = (int) strlen(dispositivo), buffer_index = 0; //Armo paquete de I/O operation // asprintf(&buffer, "%d%04d%s%04d", atoi(ENTRADA_SALIDA_ID), strlen(dispositivo), dispositivo, tiempo); serialize_data(&operation, sizeof(char), &buffer, &buffer_index); serialize_data(&dispositivo_length, sizeof(int), &buffer, &buffer_index); serialize_data(dispositivo, (size_t) dispositivo_length, &buffer, &buffer_index); serialize_data(&tiempo, sizeof(int), &buffer, &buffer_index); //Envio el paquete a KERNEL if(send(kernelSocketClient, buffer, (size_t) buffer_index, 0) < 0) { log_error(cpu_log, "entrada salida of dispositivo %s %d time send to KERNEL failed", dispositivo, tiempo); } free(buffer); }
/* * Serializa las entradas del stack en una char*. * * stack : El stack que se quiere serializar. * buffer : El buffer donde se quiere almacenar el stack serializado. * buffer_size : Variable donde se almacenara el tamanio final que terminara teniendo el buffer. */ void serialize_stack (t_stack *stack, void **buffer, int *buffer_size) { //1) Agarrro el t_list elements (t_link_element {t_link_element *head, int elements_count}) //2) voy recorriendo agarrando head y recorriendo el next //(t_link_element {void *data, t_link_element *next}) , next sera NULL para el ultimo elemento //3) a cada link element tengo que serializarle el data, que va a ser un t_stack_entry //(t_stack_entry {int pos, int cant_args, char *args, int cant_vars, char *vars, // int ret_pos, int cant_ret_vars, char *ret_vars}) t_link_element *link_actual = NULL; t_stack_entry *entrada_actual = NULL; void *stack_entry_item_buffer = NULL, *stack_list_buffer = *buffer, *next = NULL; u_int32_t cantidad_elementos_stack = 0; t_stack_entry *data = NULL; u_int32_t indice = 0; int stack_entry_item_size = 0, stack_entry_list_buffer_size = *buffer_size; //Stack / Queue t_list *elementos = stack-> elements; //Tomo la lista de elementos de la queue //t_link_element *element = elementos->head; //Tomo el primer elemento de la lista //Lista de la Queue link_actual = elementos->head; //Tomo la data del primer link de la lista cantidad_elementos_stack = (u_int32_t) elementos->elements_count; //Cantidad de links totales en el stack //El primer elemento que se agrega es la cantidad de elementos totales que tendra el stack serialize_data(&cantidad_elementos_stack,sizeof(int), buffer, buffer_size); if(link_actual == NULL || cantidad_elementos_stack == 0) { return; } for(indice = 0; indice < cantidad_elementos_stack; indice++) { entrada_actual = (t_stack_entry*) link_actual->data; //Tomo la data del primer link de la lista serialize_stack_entry(entrada_actual, buffer, buffer_size); link_actual = link_actual->next; //En la ultima iteracion, entrada_actual terminara siendo igualada a NULL } //Ya se leyeron todos los datos (t_stack_entry) del stack y se los serializaron el buffer //Tendria que haber cantidad_elementos_stack elementos en stack_entry_list_buffer //y stack_entry_list_buffer_size tendria que tener el size total del stack_entry_list_buffer }
static void mainloop(wmr_server *srv) { int fd; log_info("%s", "Entering server main loop"); for (;;) { /* POSIX.1: accept is a cancellation point */ if ((fd = accept(srv->fd, NULL, 0)) == -1) err(1, "accept"); log_debug("Client accepted, fd = %u", fd); struct byte_array data; byte_array_init(&data); serialize_data(&data, &srv->wmr->latest); while (write(fd, data.elems, data.size) >= 0); (void) close(fd); log_debug("%s", "Client socket closed"); } }
/* * Serializa una entrada del stack a un buffer, almacenando su tamanio. * * serialized_data format >> pos|cant_args|args|cant_vars|vars|cant_ret_vars|ret_vars. * * entry : La entrada que se quiere serializar. * buffer : El buffer donde se almacenara la entrada serializada. * buffer_size : Variable que terminara con el valor del tamanio final del buffer. */ void serialize_stack_entry(t_stack_entry *entry, void **buffer, int *buffer_size) { int i = 0; serialize_data(&entry->pos, sizeof(int), buffer, buffer_size); serialize_data(&entry->cant_args, sizeof(int), buffer, buffer_size); //serialize_data(&entry->args, (size_t) sizeof(t_arg)*entry->cant_args, buffer, buffer_size); for(i = 0; i < entry->cant_args; i++) { serialize_data(&(entry->args+i)->page_number, sizeof(int), buffer, buffer_size); serialize_data(&(entry->args+i)->offset, sizeof(int), buffer, buffer_size); serialize_data(&(entry->args+i)->tamanio, sizeof(int), buffer, buffer_size); } serialize_data(&entry->cant_vars, sizeof(int), buffer, buffer_size); //serialize_data(&entry->vars, (size_t) sizeof(t_var)*entry->cant_vars, buffer, buffer_size); for(i = 0; i < entry->cant_vars; i++) { serialize_data(&(entry->vars+i)->var_id, sizeof(char), buffer, buffer_size); serialize_data(&(entry->vars+i)->page_number, sizeof(int), buffer, buffer_size); serialize_data(&(entry->vars+i)->offset, sizeof(int), buffer, buffer_size); serialize_data(&(entry->vars+i)->tamanio, sizeof(int), buffer, buffer_size); } serialize_data(&entry->cant_ret_vars, sizeof(int), buffer, buffer_size); //serialize_data(&entry->ret_vars, (size_t) sizeof(t_ret_var)*entry->cant_vars, buffer, buffer_size); for(i = 0; i < entry->cant_ret_vars; i++) { serialize_data(&(entry->ret_vars+i)->page_number, sizeof(int), buffer, buffer_size); serialize_data(&(entry->ret_vars+i)->offset, sizeof(int), buffer, buffer_size); serialize_data(&(entry->ret_vars+i)->tamanio, sizeof(int), buffer, buffer_size); } serialize_data(&entry->ret_pos, sizeof(int), buffer, buffer_size); }
static lsb_err_value serialize_kvp(lsb_lua_sandbox *lsb, serialization_data *data, size_t parent) { lsb_err_value ret = NULL; lua_CFunction fp = NULL; int kindex = -2, vindex = -1; if (ignore_value_type(lsb, data, vindex, &fp)) { return ret; } ret = serialize_data(lsb, kindex, &lsb->output); if (ret) { return ret; } size_t pos = data->keys.pos; ret = lsb_outputf(&data->keys, "%s[%s]", data->keys.buf + parent, lsb->output.buf); if (ret) return ret; if (lua_type(lsb->lua, vindex) == LUA_TTABLE) { const void *ptr = lua_topointer(lsb->lua, vindex); table_ref *seen = find_table_ref(&data->tables, ptr); if (seen == NULL) { seen = add_table_ref(&data->tables, ptr, pos); if (seen != NULL) { data->keys.pos += 1; fprintf(data->fh, "%s = {}\n", data->keys.buf + pos); ret = serialize_table(lsb, data, pos); } else { snprintf(lsb->error_message, LSB_ERROR_SIZE, "lsb_serialize preserve table out of memory"); return LSB_ERR_UTIL_OOM; } } else { fprintf(data->fh, "%s = ", data->keys.buf + pos); data->keys.pos = pos; fprintf(data->fh, "%s\n", data->keys.buf + seen->name_pos); } } else if (lua_type(lsb->lua, vindex) == LUA_TUSERDATA) { void *ud = lua_touserdata(lsb->lua, vindex); table_ref *seen = find_table_ref(&data->tables, ud); if (seen == NULL) { seen = add_table_ref(&data->tables, ud, pos); if (seen != NULL) { data->keys.pos += 1; lua_pushlightuserdata(lsb->lua, data->keys.buf + pos); lua_pushlightuserdata(lsb->lua, &lsb->output); lsb->output.pos = 0; int result = fp(lsb->lua); lua_pop(lsb->lua, 2); // remove the key and the output if (!result) { size_t n = fwrite(lsb->output.buf, 1, lsb->output.pos, data->fh); if (n != lsb->output.pos) { snprintf(lsb->error_message, LSB_ERROR_SIZE, "lsb_serialize failed %s", data->keys.buf + pos); return LSB_ERR_LUA; } } } else { snprintf(lsb->error_message, LSB_ERROR_SIZE, "lsb_serialize out of memory %s", data->keys.buf + pos); return LSB_ERR_UTIL_OOM; } } else { fprintf(data->fh, "%s = ", data->keys.buf + pos); data->keys.pos = pos; fprintf(data->fh, "%s\n", data->keys.buf + seen->name_pos); } } else { fprintf(data->fh, "%s = ", data->keys.buf + pos); data->keys.pos = pos; ret = serialize_data(lsb, vindex, &lsb->output); if (!ret) { fprintf(data->fh, "%s\n", lsb->output.buf); } } return ret; }
int serve(volatile bool *running, data_t *data, int port) { int pid; int servSock, clntSock; int children; struct sockaddr_in cli_addr; struct sockaddr_in serv_addr; if (port < 0 || port > 65336) { logerr("%d is an invalid port number\r\n", port); } if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { logerr("Could not open socket\r\n"); } memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); while (*running && bind(servSock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { logerr("Could not bind to port %d, trying again in 1s\r\n", port); sleep(1); } logerr("Bound to port %d!\r\n", port); if (listen(servSock, MAXPENDING) < 0) { logerr("Listen failed\r\n"); } int flags; if (-1 == (flags = fcntl(servSock, F_GETFL, 0))) { flags = 0; } fcntl(servSock, F_SETFL, flags | O_NONBLOCK); for (children = 1; *running; children++) { unsigned int length = sizeof(cli_addr); if ((clntSock = accept(servSock, (struct sockaddr *) &cli_addr, &length)) < 0) { if (clntSock < 0) { if (errno == EWOULDBLOCK || errno == EAGAIN) { usleep(50); } else { logerr("Accept failed\r\n"); close(clntSock); } } } else { const char *content = "hi world"; std::string json = serialize_data(data); servRequest(clntSock, cli_addr, json.c_str()); close(clntSock); } } close(servSock); return 0; }