• Sábado 14 de Diciembre de 2024, 23:27

Autor Tema:  Cliente Udp (socket)  (Leído 4693 veces)

mojayu

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Cliente Udp (socket)
« en: Martes 29 de Enero de 2008, 18:36 »
0
Les comento. TEngo el siguiente codigo que trata de conectarse con un servidor mediante sockets y este le responde indicando la hora.

Código: Text
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <errno.h>
  5. #include <time.h>
  6. #include <WinSock2.h>
  7.  
  8. #define _USE_32BIT_TIME_T
  9.  
  10. #define PUERTO 37
  11. #define TAM_ENVIA 20 //Aunque luego se envia un datagrama vacio
  12.  
  13. int main (int argc, char *argv[])
  14. {
  15.   //Inicializacion de la biblioteca
  16.   int EntDevuelto;
  17.   WORD Version;
  18.   struct WSAData DatWinSock;
  19.  
  20.   Version = MAKEWORD(2,0);
  21.   EntDevuelto = WSAStartup(Version, &DatWinSock);
  22.   if (EntDevuelto != 0)
  23.   { fprintf(stderr, "No hay biblioteca Winsock.\n");
  24.     exit (-1);
  25.   }
  26.  
  27.   if ((LOBYTE(DatWinSock.wVersion)!=2) || (HIBYTE(DatWinSock.wVersion)!=0))
  28.   { fprintf(stderr, "Version incorrecta.\n");
  29.     WSACleanup();
  30.     exit (-1);
  31.   }
  32.  
  33.   int result;
  34.   SOCKET SocConexion;
  35.   struct sockaddr_in DirServidor;
  36.   unsigned long int hora;
  37.   char *strDir;
  38.   char *horaLeg;
  39.   char Peticion[TAM_ENVIA];
  40.   int longitud = sizeof(struct sockaddr);
  41.            
  42.   //Para conectar mediante nombre y no por IP
  43.   struct hostent *info;
  44.                
  45.   if (argc<2) {
  46.     printf("Direccion remota no especificadad. Usando 'localhost'\n");
  47.     strDir="127.0.0.1";
  48.     }
  49.   else strDir=argv[1];
  50.                                
  51.   //Creacion del socket de conexion
  52.   SocConexion = socket(PF_INET, SOCK_DGRAM, 0);
  53.   if (SocConexion == INVALID_SOCKET) {
  54.     fprintf(stderr, "Error %d en socket()n", WSAGetLastError());
  55.   WSACleanup();
  56.     closesocket(SocConexion);
  57.     exit (-1);
  58.     }
  59.   printf("Creacion del socket");
  60.                                                    
  61.   info = gethostbyname(strDir);
  62.                                                        
  63.   //Especificacion de la direccion del servidor
  64.   DirServidor.sin_family = AF_INET;
  65.   DirServidor.sin_port = htons(PUERTO);
  66.   //DirServidor.sin_addr.s_addr = inet_addr(strDir);
  67.   memcpy(&DirServidor.sin_addr.s_addr, info->h_addr_list[0], sizeof(DirServidor.sin_addr.s_addr));
  68.   /*                                                                
  69.   //Conectar el socket
  70.   result = connect(SocConexion, (struct sockaddr *)&DirServidor, sizeof(DirServidor));
  71.   if (result == -1) {
  72.     fprintf(stderr, "Error %d en connect(): %s\n", errno, strerror(errno));
  73.     closesocket (SocConexion);
  74.     exit (-1);
  75.     }
  76.  */
  77.   //Enviar datagrama (al ser UDP envia un datagrama vacio previo)
  78.   result = sendto(SocConexion, Peticion, sizeof(Peticion), 0, (struct sockaddr *)&DirServidor, sizeof(DirServidor));
  79.     if (result == SOCKET_ERROR) {
  80.       fprintf(stderr, "Error %d en sendto().", WSAGetLastError());
  81.     WSACleanup();
  82.       closesocket (SocConexion);
  83.       exit (-1);
  84.     }
  85.   printf("Datagrama vacio enviado");
  86.    
  87.   //Recibir respuesta
  88.   result = recvfrom(SocConexion, (char *)&hora, sizeof(hora), 0, (struct sockaddr *)&DirServidor, &longitud);
  89.     if (result == SOCKET_ERROR) {
  90.       fprintf(stderr, "Error %d en rcvfrom().", WSAGetLastError());
  91.     WSACleanup();
  92.       closesocket(SocConexion);
  93.       exit (-1);
  94.     }
  95.   printf("Respuesta recivida");
  96.                    
  97.   //Procesar la respueta
  98.   hora = ntohl(hora);
  99.   hora = hora - 2208988800lu; printf("Hora procesada");
  100.   horaLeg = ctime((time_t *)&hora);
  101.   printf("Respuesta recibida: %s", horaLeg);
  102.                              
  103.   //Cerrar la conexion
  104.   WSACleanup();
  105.   closesocket(SocConexion);
  106.   return 1;
  107. }
  108.  
  109.  

Al ejecutarlo sale la tipica ventana de dbe cerrarse el programa justo antes de la ejecucion de la funcion ctime. Al compilar me sale un warning justo en esa linea diciendo que la funcion no es segura... no se si tendra algo que ver... Si me puedieran ayudar se lo agradeceria.

Por cierto, se ejecuta por linea de comandos y para probar se puede conectar a sirio.edv.uniovi.es

mojayu

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #1 en: Martes 29 de Enero de 2008, 19:28 »
0
No he probado porque estoy en la universidad y no puedo pero es posible que el fallo sea por no poner
Código: Text
  1. #define _USE_32BIT_TIME_T
  2.  
en la primera linea del codigo?

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #2 en: Martes 29 de Enero de 2008, 19:38 »
0
No podes usar hora como si fuera time_t, al menos en VC++ 8 (.NET 2005) un time_t ocupa 8 bytes y un unsigned long int 4 bytes.

Asi si funciona:

Código: Text
  1.  
  2. time_t dt = hora;
  3. horaLeg = ctime(&dt);
  4.  
  5.  

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

mojayu

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #3 en: Miércoles 30 de Enero de 2008, 08:53 »
0
Pero el servidor manda la hora en 32 bits. Para eso pongo el primer define
Código: Text
  1. #define _USE_32BIT_TIME_T
  2.  
Ya me funciona. Lo que hice fue ponerlo en la primera linea del codigo.

En algunos ordenadores no me sale ningun warning en ctime, supongo que sea porque tienen una version mas ntigua del sdk, pero una pregunta.
Si hago la modificacion que tu me dijiste, ¿compilara igual en los pc con las versiones antiguas?

Es q yo no se que version tiene el profesor y es en el de él donde tiene que compilar y ejecutarse

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #4 en: Miércoles 30 de Enero de 2008, 09:09 »
0
Si eso (_USE_32BIT_TIME_T) esta definido antes que time.h se procese entonces tu codigo va a funcionar. Es exactamente lo que te dije, normalmente time_t 8 bytes y usando 4 tenes problemas, con ese define time_t tendra 4 bytes (32 bits) y entonces el tamaño sera el mismo en ambas variables.

El warning no sale por el tipo de la variable ya que haces un casting, sale por otra razon que realmente no viene al caso (Microsoft creo nuevas funciones mas seguras para todas las funciones que usen cadenas como parametros).

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

mojayu

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #5 en: Miércoles 30 de Enero de 2008, 13:12 »
0
Cierto, pero al cambiar ctime por ctime_s esta requiere otros parametros. Sabes como debe de llmarse para evitar el warning?

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #6 en: Miércoles 30 de Enero de 2008, 13:22 »
0
Cita de: "mojayu"
Cierto, pero al cambiar ctime por ctime_s esta requiere otros parametros. Sabes como debe de llmarse para evitar el warning?
No tiene la mas minima importancia ese warning ... si pones esta linea al principio del codigo no lo mostrara:

Código: Text
  1.  
  2. #pragma warning( disable : 4996 )
  3.  
  4.  

PD. No uses ctime_s ya que solo esta disponible desde VC++ 8.0 (.NET 2005) y no funcionara en VC++ 6 o 7.1 (.NET 2003).

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

mojayu

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #7 en: Miércoles 30 de Enero de 2008, 18:56 »
0
Muchas gracias por tu ayuda... Tengo otro problema con otro programa, es de socket tb pero esta vez es TCP por si si debo ponerlo en otro hilo avisame y lo hago  :P

Se trata de un cliente y un servidor que se comunican por sockets pero esta vez codificando con xdr. Todo me funciona perfecto pero en el servidor, cuando se desconecta el cliente me sale: violacion de segmento y se cierra cuando deberia de permanecer en espera de mas clientes porque esta en un bucle infinito.

Código: Text
  1.  
  2. #include <sys/socket.h>     // socket, send, recv. . .
  3. #include <netinet/in.h>     // sockaddr_in, htons, htonl, etc.
  4. #include <arpa/inet.h>      // inet_addr
  5. #include <unistd.h>      
  6. #include <stdlib.h>        
  7. #include <stdio.h>          
  8. #include <errno.h>        
  9. #include <string.h>        
  10. #include "tipos.h"
  11.  
  12. int main(int argc,char* argv[])
  13. {
  14.   int socketescm, sockDatos, sockEsc, ret, i, puerto;
  15.   struct sockaddr_in dir;
  16.   struct sockaddr_in dircliente;
  17.   int tamanio ,suma_par ,suma_impar;
  18.   Vector elementos; // es un vector de datos (enteros)  que se ha definido en tipos.x
  19.   FILE *f;
  20.   XDR operacion;
  21.   float resultado;
  22.   int n, numero;
  23.   casos Mens;
  24.  
  25.   printf("\nServidor en funcionamiento!!");
  26.  
  27.   // Comprobacion de que se introduzca el puerto por linea de comandos
  28.   if(argc<2)
  29.     {
  30.       printf("Error. Puerto no especificado.");
  31.       exit (-1);
  32.     }      
  33.   else
  34.     {
  35.       puerto=atoi(argv[1]);  
  36.       printf("\nUtilizando el puerto:%d\n",puerto);
  37.     }
  38.  
  39.   // Creacion socket de escucha  
  40.   sockEsc=socket(PF_INET, SOCK_STREAM, 0);
  41.   dir.sin_family=AF_INET;
  42.   dir.sin_port=htons(puerto);
  43.   dir.sin_addr.s_addr=htonl(INADDR_ANY);
  44.    ret=bind(sockEsc,(struct sockaddr *)&dir, sizeof(dir));
  45.    if (ret==-1)
  46.      {
  47.        perror("Al asignar direccion\n");
  48.        close(sockEsc);
  49.        exit(-1);
  50.      }
  51.      
  52.    // Poner socket en modo escucha
  53.    ret=listen(sockEsc, SOMAXCONN);
  54.    if (ret==-1)
  55.      {
  56.        perror("Al poner en modo escucha");
  57.        close(sockEsc);
  58.        exit(-1);
  59.      }
  60.    
  61.    while(1)
  62.      {
  63.        tamanio=sizeof(dircliente);
  64.        printf("Esperando por clientes........\n");
  65.        sockDatos = accept(sockEsc,(struct sockaddr *)&dircliente,&tamanio);
  66.        
  67.        if (sockDatos == -1)
  68.    {
  69.      perror("Error en accept\n");
  70.      exit(-1);
  71.    }
  72.        printf("Se ha conectado un cliente\n");
  73.        
  74.        elementos.Vector_val=NULL;
  75.        f=fdopen(sockDatos,"r+");
  76.        if(f==NULL)
  77.    {
  78.      printf("Error al leer los datos\n");
  79.      exit(-1);
  80.    }
  81.        
  82.        xdrstdio_create(&operacion,f,XDR_DECODE);
  83.        if(xdr_Vector(&operacion,&elementos)!=TRUE)
  84.    {
  85.      printf("Error al decodificar la estructura\n");
  86.      exit(-1);
  87.    }
  88.        if(elementos.Vector_len!=0)
  89.    {
  90.      printf("El numero de elementos es: %d\n",elementos.Vector_len);
  91.      i=0;
  92.      suma_par=0;
  93.      suma_impar=0;
  94.      while(i<elementos.Vector_len)
  95.        {
  96.           numero = elementos.Vector_val[i];
  97.     if(numero%2==1){
  98.       suma_impar=suma_impar+numero;
  99.     }
  100.     else{
  101.       suma_par=suma_par+numero;
  102.     }
  103.          i++;
  104.        }
  105.      
  106.      printf("suma_par: %d --- suma_impar: %d",suma_par,suma_impar);
  107.    
  108.      //ahora codificamos en XDR
  109.      if(suma_impar==0)
  110.        {
  111.          Mens.tipo=1;
  112.          Mens.casos_u.Mensaje="Error:division por 0";
  113.        }
  114.      else
  115.        {
  116.          resultado=(float)suma_par/(float)suma_impar;
  117.          Mens.tipo=2;
  118.          Mens.casos_u.Cociente=resultado;
  119.        }
  120.    }// fin 'if'
  121.        else  
  122.    {
  123.       Mens.tipo=1;
  124.       Mens.casos_u.Mensaje="Error: no has introducido datos\n";
  125.    }  
  126.        
  127.        f=fdopen(sockDatos,"w+");
  128.        xdrstdio_create(&operacion,f,XDR_ENCODE);
  129.        if(xdr_casos(&operacion,&Mens)!=TRUE)
  130.    {  
  131.      printf("Error al codificar los datos\n");        
  132.    }
  133.        
  134.        fflush(f);
  135.        fclose(f);
  136.  
  137.        if(suma_impar!=0)
  138.    xdr_free((xdrproc_t) xdr_Vector,(char*) elementos.Vector_val);
  139.        
  140.        close(sockDatos);
  141.  
  142.      }// fin 'while'
  143. }//fin 'main'
  144.  
  145.  

Esta vez en programacion sobre UNIX. Creo q el fallo esta en el servidor (pero no descarto nada) y que es por algo de la reserva de la memoria o que no libero algo... Muchas gracias de nuevo

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #8 en: Miércoles 30 de Enero de 2008, 19:13 »
0
Depura el servidor (o adaptalo a Winsock si queres que lo haga yo  :P) y asi sabras en que punto da el error y la razon de darlo. Despues muevo esta segunda parte a otro hilo nuevo.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.

mojayu

  • Nuevo Miembro
  • *
  • Mensajes: 17
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #9 en: Miércoles 30 de Enero de 2008, 19:20 »
0
no manejo muy bien lo de depurar y para pasarlo a winsock deberia tb pasar el cliente y el tipos.x?

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Cliente Udp (socket)
« Respuesta #10 en: Miércoles 30 de Enero de 2008, 20:27 »
0
Cita de: "mojayu"
no manejo muy bien lo de depurar y para pasarlo a winsock deberia tb pasar el cliente y el tipos.x?
Trata de depurarlo, es una habilidad muy pero muy util. Para pasarlo a Winsock y que yo pueda depurarlo (no tengo ganas ni tiempo de hacerlo) tenes que hacer lo mismo que con el programa de UDP, inicializar Winsock y usar las librerias de Windows.

Nacional y Popular En mi país la bandera de Eva es inmortal.


Queremos una Argentina socialmente justa, económicamente libre y  políticamente soberana.
¡Perón cumple, Evita dignifica!


La mano invisible del mercado me robo la billetera.