elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: (TUTORIAL) Aprende a emular Sentinel Dongle By Yapis


  Mostrar Mensajes
Páginas: 1 ... 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [46] 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 ... 235
451  Programación / Programación C/C++ / Error con send de Winsock (Solucionado) en: 1 Diciembre 2018, 23:21 pm
Muy buen dia.

Estoy trabajando con un servidor http de lo mas básico posible.

Tengo un error al momento de enviar el contenido. El navegador a veces recibe los archivos incompletos y no logro ubicar el error.



El navegador indica que solo recibe 768KB para el penultimo archivo "/test.mp3"

La salida del programa indica lo siguiente para ese archivo.



Leido indica la cantidad de bytes que a leido desde el archivo:

Código
  1. fseek(contenido,offset,SEEK_SET);
  2. leido = fread(buffer,1,size,contenido);
  3. printf("Leido %i %s\n",leido,path);
  4. if(leido != size) {
  5. fprintf(stderr,"fread() read %i vs request %i\n",leido,size);
  6. exit(0);
  7. }
  8. fclose(contenido);
  9.  

leido toma la cantidad que devuelve fread, si leido y size son distintos el programa termina inmediatamente.


Posteriormente mando ese buffer leido al comando send.

Código
  1. int send_all(SOCKET descriptor, const void *buffer, size_t length, int flags) {
  2. printf("send_all\n");
  3.    ssize_t n;
  4.    const char *p = buffer;
  5.    while (length > 0)
  6.    {
  7.        n = send(descriptor, p, length, flags);
  8. printf("send: %i bytes\n",n);
  9.        if (n <= 0)
  10.            return -1;
  11.        p += n;
  12.        length -= n;
  13.    }
  14.    return 0;
  15. }
  16.  

send all indica mediante la variable "n" la cantidad de datos enviados por send.

Asi mismo en los headers recibe correctamente el mismo numero indicado por el programa:



Asi que dado que la cantidad de items leidos por fread es la misma que la cantidad de bytes enviados por send, no entiendo por que el navegador no recibe todo el archivo, ya que al momento de tratar de reproducirlo esta incompleto.

Saludos



Al final quedo solucionado modificando la funcion send all. Por alguna razon dice que a enviado todos lo 2 MB pero el navegador  solo recibio los 700 KB. Modique la funcion para que envie de 64 bytes por vez y ahora envio el documento completo

Código
  1. int send_all(SOCKET descriptor, const void *buffer, int length, int flags) {
  2. int n,s;
  3. const char *p = buffer;
  4. while (length > 0) {
  5. s = ( length > 64 ) ? 64: length;
  6. n = send(descriptor, p, s, flags);
  7. if (n <= 0)
  8. return -1;
  9. p += n;
  10. length -= n;
  11. }
  12. return 0;
  13. }



Y el programa marca exactamente la misma cantidad.


Saludos!
452  Programación / Programación C/C++ / Re: Primero en Entrar, primero en salir FIFO, Cola o Fila en: 1 Diciembre 2018, 23:07 pm
Gracias, si no lo compile, solo lo edite y se me olvido editar el prototipo.

Saludos
453  Programación / Programación C/C++ / Re: Primero en Entrar, primero en salir FIFO, Cola o Fila en: 1 Diciembre 2018, 20:02 pm
Solo un detalle, en de_queue estás usando memcpy para mover el contenido de un vector sobre sí mismo. Cuando usas memcpy sobre dos buferes que se superponen (como en este caso) el comportamiento queda indefinido (puede que a veces funcione y otras no o puede depender del compilador...). Lo correcto en estos casos es utilizar memmove, que utiliza un bufer auxiliar y así evitar que la información del vector se pueda "machacar".

¡Saludos!

Si me imagine que si la implementación empieza de alravez puede pasar eso, lo voy editar como mentas o en su defecto con una versión iterativa con while moviendo los elementos del buffer.

Código
  1. char * de_queue(Queue *q) {
  2. char *r = NULL;
  3. int i = 0;
  4. if(q->len >= 1) {
  5. r = q->queue[0];
  6. q->len--;
  7. while(i < q->len) {
  8. q->queue[i] = q->queue[i+1];
  9. i++;
  10. }
  11. q->queue[i] = NULL;
  12. }
  13. return r;
  14. }
  15.  

Por qué free_queue dice que devuelve int y no devuelve valor alguno?

Por mala practica de programación, viejo habito de declarar las funciones como int, cuando no he definido si van a retornar valor o no.

En un momento corrijo el código.

Saludos!
454  Programación / Programación C/C++ / Re: Procesar matriz leída por un archivo txt y calcular la desviación estándar en: 1 Diciembre 2018, 01:39 am
Solo busco una guia como para empezar no que lo hagan por mí! Muchas gracias de antemano!

Por ahi hubieras empezado.

Esta el siguiente tema donde se dan algunos temas para aprender.

https://foro.elhacker.net/programacion_cc/avanzar_en_programacion_de_c_de_manera_escalonada-t490166.0.html

Si estas viendo C  date una vuelta por el siguiente tema:

https://foro.elhacker.net/programacion_cc/plantillas_programas_escolares_en_c-t489889.0.html

Ahi muestro algunas plantillas básicas que siempre piden en trabajos escolares.

Por ahi en mas te recomiendo un  libro de C

Código:
www.tecnica1lomas.com.ar/tutoriales/lenguaje_C.pdf

 y cualquier dudas aqui estamos :)

Saludos!
455  Programación / Programación C/C++ / Re: Procesar matriz leída por un archivo txt y calcular la desviación estándar en: 1 Diciembre 2018, 01:27 am
 ;-) ;-) ;-) ;-)

int main()



Fuera de bromas, por lo menos dinos si tienes el archivo.

Ya sabes leer archivos, desde C o estas viendo C++?

Saludos!
456  Programación / Programación C/C++ / Primero en Entrar, primero en salir FIFO, Cola o Fila en: 30 Noviembre 2018, 18:38 pm
No es lo mas eficiente, hay muchas cosas se podrian mejorar, en especifico la forma en la que se organizan  el arreglo de elementos actuales en la Fila,  sin embargo funciono para el proposito.

Yo se que la mayoría de estas estructuras ya están implementadas. Pero no se puede decir que eres programador si no sabes implementarlas por tu cuenta.



Código
  1. /*
  2.  El tipo de dato se puede cambiar dependiendo de la implementación que se le quiera dar, también se tendrían que cambiar los tipos de datos devueltos por las funciones
  3.  En este caso yo quería un arreglo de apuntadores char* por lo cual el contenedor es char**
  4.  */
  5.  
  6.  
  7. typedef struct str_queue {
  8. char **queue;
  9. int len;
  10. int max;
  11. }Queue;
  12.  
  13. Queue *create_queue() {
  14. Queue *r = malloc(sizeof(struct str_queue));
  15. r->len = 0;
  16. r->max = 2;
  17. r->queue = malloc(sizeof(char*)*r->max);
  18. return r;
  19. }
  20.  
  21. void free_queue(Queue *q) {
  22. if(q) {
  23. if(q->queue)
  24. free(q->queue);
  25. free(q);
  26. }
  27. }
  28.  
  29. void en_queue(Queue *q, char *ptr) {
  30. if((q->len+1) == q->max) {
  31. q->max *= 2;
  32. q->queue = realloc(q->queue,q->max*sizeof(char*));
  33. }
  34. if(q->queue != NULL) {
  35. q->queue[q->len] = ptr;
  36. q->len++;
  37. }
  38. }
  39.  
  40. char * de_queue(Queue *q) {
  41. char *r = NULL;
  42. int i = 0;
  43. if(q->len >= 1) {
  44. r = q->queue[0];
  45. q->len--;
  46. while(i < q->len) {
  47. q->queue[i] = q->queue[i+1];
  48. i++;
  49. }
  50. q->queue[i] = NULL;
  51. }
  52. return r;
  53. }

Yo en su momento lo utilize para un post, donde realizaba una versión iterativa y necesitaba almacenar en una Cola el listado de los directorios que aun faltaba por recorrer:

problema de memoria con readdir (Solucionado)

Ejemplo de uso:

Código
  1. int main() {
  2. char *cadenas[10] = { "Cadena_0","Cadena_1","Cadena_2","Cadena_3","Cadena_4","Cadena_5","Cadena_6","Cadena_7","Cadena_8","Cadena_9"};
  3. char *actual;
  4. int index1,index2,i =0;
  5. srand(time(NULL));
  6. Queue *q = create_queue();
  7. while(i < 10) {
  8. index1 = rand() % 10;
  9. index2 = rand() % 10;
  10. printf("Agregando a la fila: %s\n",cadenas[index1]);
  11. en_queue(q,cadenas[index1]);
  12. printf("Agregando a la fila: %s\n",cadenas[index2]);
  13. en_queue(q,cadenas[index2]);
  14. printf("Saliendo de la fila %s\n",de_queue(q));
  15. i++;
  16. }
  17. free_queue(q);
  18. }
  19.  

Como es randon la salida es variada, pero podemos observar el funcionamiento:



Código:
Agregando a la fila: Cadena_5
Agregando a la fila: Cadena_5
Saliendo de la fila Cadena_5
Agregando a la fila: Cadena_8
Agregando a la fila: Cadena_2
Saliendo de la fila Cadena_5
Agregando a la fila: Cadena_5
Agregando a la fila: Cadena_7
Saliendo de la fila Cadena_8
Agregando a la fila: Cadena_8
Agregando a la fila: Cadena_7
Saliendo de la fila Cadena_2
Agregando a la fila: Cadena_9
Agregando a la fila: Cadena_2
Saliendo de la fila Cadena_5
Agregando a la fila: Cadena_1
Agregando a la fila: Cadena_3
Saliendo de la fila Cadena_7
Agregando a la fila: Cadena_8
Agregando a la fila: Cadena_5
Saliendo de la fila Cadena_8
Agregando a la fila: Cadena_0
Agregando a la fila: Cadena_3
Saliendo de la fila Cadena_7
Agregando a la fila: Cadena_4
Agregando a la fila: Cadena_0
Saliendo de la fila Cadena_9
Agregando a la fila: Cadena_7
Agregando a la fila: Cadena_1
Saliendo de la fila Cadena_2



Funcion actualizada de de_queue

Código
  1. char * de_queue(Queue *q) {
  2. char *r = NULL;
  3. int i = 0;
  4. if(q->len >= 1) {
  5. r = q->queue[0];
  6. q->len--;
  7. while(i < q->len) {
  8. q->queue[i] = q->queue[i+1];
  9. i++;
  10. }
  11. q->queue[i] = NULL;
  12. }
  13. return r;
  14. }
  15.  
457  Programación / Programación C/C++ / Re: problema de memoria con readdir (Solucionado) en: 30 Noviembre 2018, 04:57 am
Segun la documentacion, readdir usa memoria estatica, de modo que no corresponde usar free() sobre lo que se retorna.

Excelente, segun veo usa parte de la misma estrucutra original del directorio pasado como parametro. o algo asi alcance a ver.

Sugiero reemplazar esto de pedir y liberar memoria en cada vuelta del while por solo pedir memoria cuando es necesario pedirla, y no liberarla en cada vuelta, solo liberarla al final del while.

Voy aplicarlo gracias!, ya que si termina siendo mas eficiente, por que evitaria tantas llamadas a malloc como sea posible.

Creo que ya encontre la solucion, según veo no es problema de memoria por liberar, es problema de la implementación recursiva de la función.

La solución recursiva es la que menos memoria utiliza.

Saludos!
458  Programación / Programación C/C++ / Re: Avanzar en programación de c++ de manera escalonada en: 29 Noviembre 2018, 19:00 pm
Pues segun mi recomendación personal podria ser lo siguiente:

Decisiones Basicias:

if, else, switch

Ciclos repetitivos

while, do-while, for ¿Saber cuando es mejor uno u otro?

Casos Itetivos, casos recursivos ¿Saber cuando es mejor uno u otro?

Memoria dinámica en caso de C++ new/delete, aunque un poco de background seria conveniente malloc/realloc/free

Archivos lectura, escritura, actualización, diferencia entre archivos binarios y de texto, Aunque esto ultimo confunde a mucha gente, es lo mismo, solo tienes que estar conciente de como vasa manejar los datos.

Ordenamiento de datos
Liststas Ligagamas, Doblemente Ligadas, Circulares

Estrucuturas de datos
Aparte de las anteriores, Pilas Arboles Binarios, Arboles, Grafos (El santo grial de la programación)

Ya terminado lo anterior, tal vez funciones de red

Trabajando con Sockets, para adentrarte en  el mundo de los protocolos de Red, como "hablar" http, ftp etc...
(Aqui seria muy didactivo programar un WEB spider)

Un poco de criptografia tal vez.

Y pues en general el cielo es el limite.

Tengo 15 años programando en C y C++ y aun estoy aprendiendo cosas nuevas.

Saludos
459  Programación / Programación C/C++ / problema de memoria con readdir (Solucionado) en: 29 Noviembre 2018, 18:47 pm
Muy buen dia.

Problema: La memoria utilizada por el programa aumenta y no disminuye

Solución: No es un problema, es la memoria que se genera por el paradigma de la recursividad, esto es: que al llamar a la misma función de forma recursiva, el Stack Frame de la memoria que utiliza cada una de las llamadas a la función se acumule.

Intente aplicar una solucion de forma Iterativa, guardando el Path de los directorios que faltan por leer en una Queue, pero utiliza mas memoria  que la solucion recursiva.

readdir devuelve un apuntador de la estructura (struct dirent)
Mas info: https://linux.die.net/man/3/readdir

El cual creo que es el causante de este POST.

Versión Corta

¿Quien controla el Apuntador entregado por readdir?

Es memoria estatica y no se debe de liberar

Código
  1. directorio_archivo_temporal = readdir(directorio)

Al momento de tratar de liberar dicho apuntador, el programa se cuelga...

Código
  1. while(directorio_archivo_temporal = readdir(directorio) ) {
  2. //etc..
  3. free(directorio_archivo_temporal);
  4. }
  5.  

El problema radica en que la memoria del programa solo aumenta y no disminuye.

Codigo de la version corta funcionando
Código
  1. #include<sys/stat.h>
  2. #include<sys/types.h>
  3. #include<dirent.h>
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include<string.h>
  7.  
  8. int is_regular_file(const char *path);
  9.  
  10. int procesar_directorio(char *path);
  11.  
  12. int main(int argc,char **argv) {
  13. switch(argc){
  14. case 2: //Se espera directorio
  15. procesar_directorio(argv[1]);
  16. break;
  17. default:
  18. printf("Numero de argumentos no esperado\n");
  19. break;
  20. }
  21.  
  22. }
  23.  
  24. int is_regular_file(const char *path) {
  25. struct stat path_stat;
  26. stat(path, &path_stat);
  27. return S_ISREG(path_stat.st_mode);
  28. }
  29.  
  30. int procesar_directorio(char *path) {
  31. DIR *directorio;
  32. struct dirent *directorio_archivo_temporal;
  33. char *path_copy;
  34. int len_path;
  35. char *path_temporal;
  36. int len_path_temporal;
  37. directorio = opendir(path);
  38. if(directorio != NULL) {
  39. len_path = strlen(path);
  40. path_copy = malloc(len_path+2);
  41. memcpy(path_copy,path,len_path);
  42. if(path_copy[len_path - 1] == '\\' ){
  43. path_copy[len_path] = '\0';
  44. }
  45. else {
  46. path_copy[len_path] = '\\';
  47. path_copy[len_path+1] = '\0';
  48. len_path++;
  49. }
  50. while(directorio_archivo_temporal = readdir(directorio) ) {
  51. len_path_temporal = strlen(directorio_archivo_temporal->d_name);
  52. path_temporal = malloc(len_path+len_path_temporal+1);
  53. path_temporal[len_path+len_path_temporal] = '\0';
  54. sprintf(path_temporal,"%s%s",path_copy,directorio_archivo_temporal->d_name);
  55. if(is_regular_file(path_temporal)) {
  56. printf("%s\n",path_temporal);
  57. }
  58. else { //Directorio?
  59. if( len_path_temporal > 2 ) { //not .. or .
  60. procesar_directorio(path_temporal); //recursivamente
  61. }
  62. }
  63. free(path_temporal);
  64. }
  65. free(path_copy);
  66. closedir(directorio);
  67. }
  68. }
  69.  








Versión extensa

Aquí esta toda la Letanía

Estoy realizando un programa que lea de forma Recursiva un directorio dado y liste los archivos en pantalla. Nada del otro mundo. Asi mismo estoy haciendo que el formato de salida sea el formato tipo UNIX /bla/bla/bla en lugar del formato de windows C:\lalala\lalalala.txt

Esto con el objetivo de virtualizar el path de subdirectorios específicos para otro programa pero eso ya es harina de otro costal.

El problema es que cuando listo Cualquier carpeta con muchos subdirectorios como la unidad C:\  el programa en empieza usando lo clasico unos 400 KB y termina utilizando 800 KB o mas dependiendo de la carpeta que este listada.

El dia Ayer publique un post parecido:
Problema de memoria en miniservidor usando Winsock (Solucionado)

En el cual se estaba cerrando el socket de forma incorrecta.

En este caso creo que es problema del apuntador devuelto por readdir.

Código del programa funcionando:

Código
  1. #include<sys/stat.h>
  2. #include<sys/types.h>
  3. #include<dirent.h>
  4. #include<stdio.h>
  5. #include<stdlib.h>
  6. #include<string.h>
  7.  
  8. int fsize(const char *filename);
  9. int is_regular_file(const char *path);
  10.  
  11. int procesar_directorio(char *path,char *virtual_path);
  12.  
  13. int main(int argc,char **argv) {
  14. switch(argc){
  15. case 2: //Se espera directorio
  16. procesar_directorio(argv[1],"/");
  17. break;
  18. case 3: //Se espera archivo + nombre de directorio de destino.
  19. break;
  20. default:
  21. printf("Numero de argumentos no esperado\n");
  22. break;
  23. }
  24.  
  25. }
  26.  
  27. int is_regular_file(const char *path) {
  28. struct stat path_stat;
  29. stat(path, &path_stat);
  30. return S_ISREG(path_stat.st_mode);
  31. }
  32.  
  33. int fsize(const char *filename) {
  34.    struct stat st;
  35.    if (stat(filename, &st) == 0)
  36.        return st.st_size;
  37.    return -1;
  38. }
  39.  
  40. int procesar_directorio(char *path,char *virtual_path) {
  41. DIR *directorio;
  42. struct dirent *directorio_archivo_temporal,*result;
  43.  
  44. char *path_copy;
  45. char *virtual_path_copy;
  46. int len_path,len_virtual_path;
  47.  
  48. char *path_temporal;
  49. char *virtual_path_temporal;
  50. int len_path_temporal;
  51. int len_virtual_path_temporal;
  52.  
  53.  
  54. directorio = opendir(path);
  55. if(directorio != NULL) {
  56.  
  57. len_path = strlen(path);
  58. len_virtual_path = strlen(virtual_path);
  59.  
  60. virtual_path_copy = malloc(len_virtual_path+2);
  61. path_copy = malloc(len_path+2);
  62. memcpy(path_copy,path,len_path);
  63. memcpy(virtual_path_copy,virtual_path,len_virtual_path);
  64.  
  65. if(path_copy[len_path - 1] == '\\' ){
  66. path_copy[len_path] = '\0';
  67. }
  68. else {
  69. path_copy[len_path] = '\\';
  70. path_copy[len_path+1] = '\0';
  71. len_path++;
  72. }
  73. if(virtual_path_copy[len_virtual_path - 1] == '/' ){
  74. virtual_path_copy[len_virtual_path] = '\0';
  75. }
  76. else {
  77. virtual_path_copy[len_virtual_path] = '/';
  78. virtual_path_copy[len_virtual_path+1] = '\0';
  79. len_virtual_path++;
  80. }
  81. /*
  82. directorio_archivo_temporal = calloc(1,sizeof(struct dirent));
  83. result == NULL;
  84. */
  85. //while(readdir_r(directorio,directorio_archivo_temporal,&result) == 0 && result != NULL){
  86. while(directorio_archivo_temporal = readdir(directorio) ) {
  87.  
  88. len_path_temporal = strlen(directorio_archivo_temporal->d_name);
  89. //printf("readdir point to %p\n",directorio_archivo_temporal);
  90. //printf("Len %i : %s\n",len_path_temporal,directorio_archivo_temporal->d_name);
  91.  
  92. path_temporal = malloc(len_path+len_path_temporal+1);
  93. virtual_path_temporal = malloc(len_virtual_path + len_path_temporal+1);
  94.  
  95. path_temporal[len_path+len_path_temporal] = '\0';
  96. virtual_path_temporal[len_virtual_path+len_path_temporal] = '\0';
  97.  
  98. sprintf(path_temporal,"%s%s",path_copy,directorio_archivo_temporal->d_name);
  99. sprintf(virtual_path_temporal,"%s%s",virtual_path_copy,directorio_archivo_temporal->d_name);
  100.  
  101. if(is_regular_file(path_temporal)) {
  102. //printf("Archivo :\"%s\"\n",path_temporal);
  103. printf("%s\n",virtual_path_temporal);
  104. }
  105. else { //Directorio?
  106. if( len_path_temporal > 2 ) { //not .. or .
  107. procesar_directorio(path_temporal,virtual_path_temporal); //recursivamente
  108. }
  109. }
  110. free(path_temporal);
  111. free(virtual_path_temporal);
  112. }
  113. //free(directorio_archivo_temporal);
  114.  
  115.  
  116.  
  117. free(path_copy);
  118. free(virtual_path_copy);
  119. closedir(directorio);
  120. }
  121. else {
  122. printf("El directorio \"%s\" no es un directorio valido\n",path);
  123. }
  124. }
  125.  

Funciona bien, recibe parametros de entrada, ejemplo

Ejemplo

Código:
C:\>generar_contenido.exe contenido
/index.html

Le agregue un getchar al final del archivo para poder ver con cuanta memoria termina el programa. Para carpetas sin tanto subdirecorio no hay problema, el detalle es cuando se trata de todo un disco...

Imagen:


Ya he validado que todos los apuntadores que yo genero de forma dinámica son liberados en su totalidad, esto mediante re implementaciones de malloc,calloc,realloc y free como describo en el siguiente post: ¿He liberado todos los apuntadores?

Imagen:


Con lo cual considero que el problema es el apuntador devuelto por readdir.

Intente cambiar el siguiente pedazo de codigo

Código
  1. while(directorio_archivo_temporal = readdir(directorio) ) {
  2. //etc...
  3. }
  4.  

por

Código
  1. while(directorio_archivo_temporal = readdir(directorio) ) {
  2. //etc..
  3. free(directorio_archivo_temporal);
  4. }
  5.  

Pero el programa se queda colgado por un rato y finaliza, seguramente por tratar de escribir en memoria que no esta asignada...

Intente implementarlo con readdir_r utilizando mi propio apuntador previamente asignado..

Código
  1. while(readdir_r(directorio,directorio_archivo_temporal,&result) == 0 && result != NULL){
  2.  

Pero por alguna razon MinGW no lo tiene implementado, y segun he visto ya esta deprecated, entonces ¿Cual puede ser la solución?

Saludos!



Pordon por el Post tan largo, aqui esta su patata

460  Seguridad Informática / Hacking Wireless / Re: Necesito saber si mi tarjeta de red soporta modo monitor no sé como en: 29 Noviembre 2018, 05:52 am
Si ya tienes linux instalado con la suite de aircrack puedes checar este tutorial

https://www.aircrack-ng.org/doku.php?id=compatibility_drivers

Código:
You can use the iw command to get a full list of all capabilities of a physical wireless card:

Linux command

Código:
 iw list
Páginas: 1 ... 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [46] 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 ... 235
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines