Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - VladisMSX1

#1
 :-[ :-[ :-[ No había visto el ; justo al final de la declaración de las funciones. El caso es que en mi código en Dev-C++ no está (sino, lógicamente, no compilaría) así que acabo de alucinar. No lo he visto sencillamente porque no esperaba que ahí hubiera un ; y ni me había fijado. Madre mía.... :-[

De un plumazo han desaparecido un montón de errores, entre ellos los que decían que las variables no estaban declaradas (de ahí que no le viera sentido)

Las variables de canal_a y canal_b están bien declaradas en mi código en Dev-C++. Lógicamente canal_1 debería ser canal_a.

En fin, fallazos de novato matao... creo que tenía tal dolor de cabeza que no he visto esos fallos aunque saltaban a la vista :huh: a ver si ahora la cosa funciona mejor.

Muchas gracias!
#2
Decidí no ponerlo porque pensaba que era un problema "genérico" de cualquier código escrito en el compilador Dev-C++ al intentar portarlo a Visual Studio 2010  :xD

Aquí lo pongo:


#include "xtrautil.h"
#include <conio.h>         //Librería de headers, no definida en estandard C
#include <stdlib.h>        //Librería de propósito general para gestión de memoria
#include <iostream>        //Librería de funciones de E/S de datos
#include <stdio.h>         //Librería de funciones E/S Estandard
#include <windows.h>       //Librería de compatibilidad con windows
#include <string.h>        //Definición de macros, constantes, funciones, etc
#include <winsock.h>       //Librería de manejo de sockets Winsock
#define ip "192.168.0.255" //IP del servidor (A la que conectar)
using namespace std;

void doEtherValue( long canal, long valor, XtraInfo * xtraInfo );
{
      int i;
      if ((canal<1) || (canal>512) || (valor>255) || (valor<0))
         {
         system("cls");
         cout<<"ERROR - Numero de canal o valor indicado fuera de rango\nPulsa cualquier tecla para continuar...";
         getch();
         }
      else
          {
          //ARRAY DE SECUENCIA
          char secuencia[1];
          //Aplicamos el valor secuencia al punto CERO, ya que los arrays se definen con el entero de su tamaño, pero su primer valor es el 0, no el 1
          secuencia[0]=0;
         
          //ARRAY DE VALORES DE CANALES
          int k;
          char valores[526];
          for (k=0; k<526; k++)
             {
             valores[k]=0;
             }
          //Asignación del valor al canal
              valores[canal-1]=valor;
         
          /*
           /////////////////////////////////////////////////////////////////////////////
           ||                                                                         ||
           ||                                                                         ||
           ||                            *******CONEXION*******                       ||
           ||                                                                         ||
           ||                                                                         ||
           /////////////////////////////////////////////////////////////////////////////
           */
         
          system("cls");//Borramos la pantalla para eliminar las lineas mostradas en el menú

         /* Primero abrimos el socket Winsock. Tenemos varias opciones para definir
         el tipo de socket que vamos a crear:
               Familia del protocolo:
                       AF_INET: Para conexión con máquinas conectadas a Internet
                       AF-UNIX: Para conexion con máquinas LINUX
                       AF_NS:   Para conexión con máquinas XEROX
                       AF_CCITT:Para conexión con protocolos CCITT,X25...
               Tipo de socket:
                       SOCKET_STREAM: Para TCP
                       SOCKET_DGRAM:  Para UDP
                       SOCKET_RAW:    Para IP
               Protocolo:
                       PPROTO_TCP: Como dice su nombre, para protocolo TCP
                       PPROTO_UDP: Como dice su nombre, para protocolo UDP

         Así pues para una conexión UDP normal, el código sería: */

         WSADATA wsa; // Winshock
         int sock;//Descriptor del socket.
         struct sockaddr_in direccion; //Datos del servidor a conectar

         WSAStartup(MAKEWORD(2,0),&wsa);

         /* -Después creamos una structura (struct), en la que definiremos el tipo de
          -protocolo a utilizar para la conexion,
          -despues el puerto por el que deve conectarse nuestro cliente y
          -por último la ip a la que conectara nuestro cliente. */
         
         char buf[531];       // Tamaño del mensaje a enviar
         int puerto=6454;     // puerto del servidor a conectar
       
         if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1 )
            {
            // Creamos el socket mientras creamos el primer filtro de error
            printf("PROBLEMA AL CREAR EL SOCKET");
            getch();
            exit(0);
            }
         else
           {
           printf("SOCKET CREADO CORRECTAMENTE\n\n");
           /* Ahora procedemos a insertar la informacion en la structura.
            *** IMPORTANTE *** Es una structura especial para socket; sin_family, sin_port .... */
           
           // **** DATOS DE LA ESTRUCTURA CON LOS DATOS DE DESTINO
           direccion.sin_family=AF_INET; // AF_inet con el protocolo UDP (Información en el paso anterior)
           direccion.sin_port=htons(puerto); //Usamos HTONS para transformar el numero de puerto a uno entendible para el socket.
           direccion.sin_addr.s_addr=inet_addr(ip); // Y agregamos la IP
       
           /*
               Despues de crear el socket y la structura con los datos pertinentes,
               podemos conectar por fin al servidor, que en los sockets TCP se haría
               con CONNECT, pero en los UDP se hace bindeando el socket al cliente con
               BIND.
               
               Desglosado en partes, la línea siguiente se compone de:
               connect: Comando de conexión.
               sock: Define el socket que hemos creado en el paso 1
               struct sockaddr*:Aqui va la structura anteriormente paso 2 creada con todos los datos para conectar,ip,protocolo,puerto, (&dirrecion)
               sizeof: Utilizamos el operador sizeof para indicar la longuitud de la estructura
               Así es como queda la estructura final: connect(sock, (struct sockaddr*)&direccion,sizeof(direccion));
               
               A continuación definimos el socket:
               Bind: Crea la definición del socket que vamos a utilizar.
               Sock: Aqui va la structura anteriormente creada (struct sockaddr_in server;)con todos los datos del servidor,ip,protocolo,puerto) &server
               Sizeof: Utilizamos el operador sizeof para obtener la longuitud de la estructura
               Y el resultado es: bind(sock,(struct sockaddr *)&server,sizeof(server));
           */
             
           struct sockaddr_in me;
           memset(&me, 0, sizeof(me));
           me.sin_family = AF_INET;
           me.sin_addr.s_addr = htonl(INADDR_ANY);
           me.sin_port = htons(puerto);
       
           if (bind(sock, (struct sockaddr *)&me, sizeof(me))==-1)
               {
               puts("BIND FAILED - ERROR");
               }
           else
               {
               puts("BIND ASIGNADO CON EXITO");
               }
       
           /*
              Como las conexiones UDP no son orientadas a conexión, no podemos utilizar connect,
              ya que entraría en conflicto con bind. Así pues, lo dejamos comentado y listo para
              un posible socket TCP
           
              if(connect(sock,(struct sockaddr*)&direccion,sizeof(direccion))==-1)
                 {//conectamos al servidor aplicando el segundo filtro:
                 printf("ERROR AL CONECTAR");
                 getch();
                 exit(0);
                 }  
         
             //Confirmamos el éxito de la conexión
             printf("CONECTADO CORRECTAMENTE\n\n");
         
           */
         
           /*
           /////////////////////////////////////////////////////////////////////////////
           ||                                                                         ||
           ||                                                                         ||
           ||             DEFINICION DE LA CADENA DE DATOS A ENVIAR(buf)              ||
           ||                                                                         ||
           ||                                                                         ||
           /////////////////////////////////////////////////////////////////////////////
           */
         
           char total[531]; //Variable maestra en la que iremos introduciendo cada sección del paquete ArtNet Originalmente(531)
           char l_total; //Variable para introducir la suma de longitudes de los fragmentos del paquete
           char puntero; //Puntero para las operaciones de concatenación
           char cabecera[8]={65 , 114 , 116 , 45 , 78 , 101 , 116 , 0}; //Cabecera del paquete
           char opcode[2]={0, 80}; // OpCode (Originalmente 0 (El bit bajo primero) y 80)
           char version[2]={0 , 14}; //Indicador de la versión (Originalmente 0 y 14)
           char phisycal[1]={2}; //Subred. Originalmente 0
           char universo[2]={0 , 0}; //Define el universo en el que vamos a trabajar
           char lon_val[2]={2 , 0}; //Indice de la longitud de valores (Originalmente 2 y 0)  
           
           //Contamos el tamaño de cada cadena para obtener el tamaño final de la cadena de trabajo.
           const unsigned int array_sizes[] = {sizeof(cabecera) , sizeof(opcode) , sizeof(version) , sizeof(secuencia) , sizeof(phisycal) , sizeof(universo) , sizeof(lon_val) , sizeof(valores)};
         
           //Definimos los arrays y punteros para concatenar las cadenas
           char *arrays[] = {
                   cabecera,
                   opcode,
                   version,
                   (char*) secuencia,
                   phisycal,
                   universo,
                   lon_val,
                   (char*) valores};
             
           unsigned int i, bytes_copiados, total_bytes;
         
          //Realizamos la copia de las cadenas
          for(i = total_bytes = 0; i < sizeof(arrays) / sizeof(char *); total_bytes += array_sizes[i], i++);
         
          char *mensaje = (char *) malloc (total_bytes);
         
          //Aplicamos un filtro de error que indique un posible overflow
          if(!mensaje){
                       perror("Error al reservar memoria");
                       getch();
          }
          //Aplicamos la copia con la función memcpy
          for(i = bytes_copiados = 0; i < sizeof(array_sizes) / sizeof(int); bytes_copiados += array_sizes[i], i++)
          memcpy(mensaje + bytes_copiados, arrays[i], array_sizes[i]);
         
          //Mostramos el array de almacenaje (mensaje) e introducimos los datos en la cadena final
          cout<<"Estos son los datos enviados:"<<"\n\n";
          //Bucle de asignación de bytes al array de envio
          for(i = 0; i < total_bytes; i++)
               {
               //Mostramos en pantalla el byte
               printf("%d ", (unsigned char) mensaje[i]);
               //Copiamos ese mismo byte en el array de envio
               buf[i]=("%d ", (unsigned char) mensaje[i]);
               }
               
          cout<<"\nTotal de bytes:"<<total_bytes<<"\n";
       
          free(mensaje);
         
          /*Comprobamos que los datos se han transmitido correctamente al array de trabajo buf:
         
          cout<<"\n\nCOMPROBACION\n\n";
          for (i=0; i<531; i++)
              cout<<buf[i]<<" ";
         */
         
         /*
         /////////////////////////////////////////////////////////////////////////////
         ||                                                                         ||
         ||                                                                         ||
         ||          ENVIO DE DATOS AL DISPOSITIVO Y CIERRE DE CONEXIÓN             ||
         ||                                                                         ||
         ||                                                                         ||
         /////////////////////////////////////////////////////////////////////////////
       
         Ahora que ya estamos conectados al servidor,ya podemos enviarle informacion con la funcion (send).
         Este sería el caso de un socket TCP. Al ser un socket UDP, utilizamos la función sendto, que tiene
         una sintaxis distinta. Estos son sus elementos y las diferentes sintaxis de uso de las dos funciones:
           
               send: definicion del socket que creamos en el paso 1
               buf:variable con la informacion a enviar
               Sizeof: Utilizamos el operador sizeof para indicar la longuitud de la variable
               Flag: lo dejamos en 0
         El resultado final:
             
              PARA SEND:
                   send(sock,buf,sizeof(buf),0);
             
              PARA SENDTO:
                   (sock,buf,sizeof(buf),0,(struct sockaddr*)&receiver_addr,sizeof(receiver_addr));

         */
       
             if(sendto(sock,buf,sizeof(buf),0,(struct sockaddr*)&direccion,sizeof(direccion))==-1)
                {//Aplicamos el filtro de error de envio
                printf("ERROR ENVIANDO");
                getch();
                exit(0);
                }
             else
                 {//Confirmamos el éxito del envío
                  closesocket(sock);
                  //puts("\nMensaje enviado, pulsa una tecla para continuar");
                  //getch();
                 }
              };
          }
};

void doEtherRangeValue( long canal_1, long canal_2, long valor, XtraInfo * xtraInfo );
{
      int i;
      if ((canal_a<1) || (canal_a>512) || (canal_b>512) || (canal_a>canal_b) || (valor>255) || (valor<0))
         {
         system("cls");
         cout<<"ERROR - Numero de canal o valor indicado fuera de rango\nPulsa cualquier tecla para continuar...";
         getch();
         }
      else
          {
          //ARRAY DE VALORES DE CANALES
          int k;
          char valores[526];
          for (k=0; k<526; k++)
             {
             valores[k]=0;
             }
          //ARRAY DE SECUENCIA
          char secuencia[1];
          //Aplicamos el valor secuencia al punto CERO, ya que los arrays se definen con el entero de su tamaño, pero su primer valor es el 0, no el 1
          secuencia[0]=0;
          //Bucle de asignación de valores del rango
          for (i=(canal_a-1); i<(canal_b); i++)
              {
              valores[i]=valor;
              }
         
          /*
           /////////////////////////////////////////////////////////////////////////////
           ||                                                                         ||
           ||                                                                         ||
           ||                            *******CONEXION*******                       ||
           ||                                                                         ||
           ||                                                                         ||
           /////////////////////////////////////////////////////////////////////////////
           */
         
          system("cls");//Borramos la pantalla para eliminar las lineas mostradas en el menú

         /* Primero abrimos el socket Winsock. Tenemos varias opciones para definir
         el tipo de socket que vamos a crear:
               Familia del protocolo:
                       AF_INET: Para conexión con máquinas conectadas a Internet
                       AF-UNIX: Para conexion con máquinas LINUX
                       AF_NS:   Para conexión con máquinas XEROX
                       AF_CCITT:Para conexión con protocolos CCITT,X25...
               Tipo de socket:
                       SOCKET_STREAM: Para TCP
                       SOCKET_DGRAM:  Para UDP
                       SOCKET_RAW:    Para IP
               Protocolo:
                       PPROTO_TCP: Como dice su nombre, para protocolo TCP
                       PPROTO_UDP: Como dice su nombre, para protocolo UDP

         Así pues para una conexión UDP normal, el código sería: */

         WSADATA wsa; // Winshock
         int sock;//Descriptor del socket.
         struct sockaddr_in direccion; //Datos del servidor a conectar

         WSAStartup(MAKEWORD(2,0),&wsa);

         /* -Después creamos una structura (struct), en la que definiremos el tipo de
          -protocolo a utilizar para la conexion,
          -despues el puerto por el que deve conectarse nuestro cliente y
          -por último la ip a la que conectara nuestro cliente. */
         
         char buf[531];       // Tamaño del mensaje a enviar
         int puerto=6454;     // puerto del servidor a conectar
       
         if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1 )
            {
            // Creamos el socket mientras creamos el primer filtro de error
            printf("PROBLEMA AL CREAR EL SOCKET");
            getch();
            exit(0);
            }
         else
           {
           printf("SOCKET CREADO CORRECTAMENTE\n\n");
           /* Ahora procedemos a insertar la informacion en la structura.
            *** IMPORTANTE *** Es una structura especial para socket; sin_family, sin_port .... */
           
           // **** DATOS DE LA ESTRUCTURA CON LOS DATOS DE DESTINO
           direccion.sin_family=AF_INET; // AF_inet con el protocolo UDP (Información en el paso anterior)
           direccion.sin_port=htons(puerto); //Usamos HTONS para transformar el numero de puerto a uno entendible para el socket.
           direccion.sin_addr.s_addr=inet_addr(ip); // Y agregamos la IP
       
           /*
               Despues de crear el socket y la structura con los datos pertinentes,
               podemos conectar por fin al servidor, que en los sockets TCP se haría
               con CONNECT, pero en los UDP se hace bindeando el socket al cliente con
               BIND.
               
               Desglosado en partes, la línea siguiente se compone de:
               connect: Comando de conexión.
               sock: Define el socket que hemos creado en el paso 1
               struct sockaddr*:Aqui va la structura anteriormente paso 2 creada con todos los datos para conectar,ip,protocolo,puerto, (&dirrecion)
               sizeof: Utilizamos el operador sizeof para indicar la longuitud de la estructura
               Así es como queda la estructura final: connect(sock, (struct sockaddr*)&direccion,sizeof(direccion));
               
               A continuación definimos el socket:
               Bind: Crea la definición del socket que vamos a utilizar.
               Sock: Aqui va la structura anteriormente creada (struct sockaddr_in server;)con todos los datos del servidor,ip,protocolo,puerto) &server
               Sizeof: Utilizamos el operador sizeof para obtener la longuitud de la estructura
               Y el resultado es: bind(sock,(struct sockaddr *)&server,sizeof(server));
           */
             
           struct sockaddr_in me;
           memset(&me, 0, sizeof(me));
           me.sin_family = AF_INET;
           me.sin_addr.s_addr = htonl(INADDR_ANY);
           me.sin_port = htons(puerto);
       
           if (bind(sock, (struct sockaddr *)&me, sizeof(me))==-1)
               {
               puts("BIND FAILED - ERROR");
               }
           else
               {
               puts("BIND ASIGNADO CON EXITO");
               }
       
           /*
              Como las conexiones UDP no son orientadas a conexión, no podemos utilizar connect,
              ya que entraría en conflicto con bind. Así pues, lo dejamos comentado y listo para
              un posible socket TCP
           
              if(connect(sock,(struct sockaddr*)&direccion,sizeof(direccion))==-1)
                 {//conectamos al servidor aplicando el segundo filtro:
                 printf("ERROR AL CONECTAR");
                 getch();
                 exit(0);
                 }  
         
             //Confirmamos el éxito de la conexión
             printf("CONECTADO CORRECTAMENTE\n\n");
         
           */
         
           /*
           /////////////////////////////////////////////////////////////////////////////
           ||                                                                         ||
           ||                                                                         ||
           ||             DEFINICION DE LA CADENA DE DATOS A ENVIAR(buf)              ||
           ||                                                                         ||
           ||                                                                         ||
           /////////////////////////////////////////////////////////////////////////////
           */
         
           char total[531]; //Variable maestra en la que iremos introduciendo cada sección del paquete ArtNet Originalmente(531)
           char l_total; //Variable para introducir la suma de longitudes de los fragmentos del paquete
           char puntero; //Puntero para las operaciones de concatenación
           char cabecera[8]={65 , 114 , 116 , 45 , 78 , 101 , 116 , 0}; //Cabecera del paquete
           char opcode[2]={0, 80}; // OpCode (Originalmente 0 (El bit bajo primero) y 80)
           char version[2]={0 , 14}; //Indicador de la versión (Originalmente 0 y 14)
           char phisycal[1]={2}; //Subred. Originalmente 0
           char universo[2]={0 , 0}; //Define el universo en el que vamos a trabajar
           char lon_val[2]={2 , 0}; //Indice de la longitud de valores (Originalmente 2 y 0)  
           
           //Contamos el tamaño de cada cadena para obtener el tamaño final de la cadena de trabajo.
           const unsigned int array_sizes[] = {sizeof(cabecera) , sizeof(opcode) , sizeof(version) , sizeof(secuencia) , sizeof(phisycal) , sizeof(universo) , sizeof(lon_val) , sizeof(valores)};
         
           //Definimos los arrays y punteros para concatenar las cadenas
           char *arrays[] = {
                   cabecera,
                   opcode,
                   version,
                   (char*) secuencia,
                   phisycal,
                   universo,
                   lon_val,
                   (char*) valores};
             
           unsigned int i, bytes_copiados, total_bytes;
         
          //Realizamos la copia de las cadenas
          for(i = total_bytes = 0; i < sizeof(arrays) / sizeof(char *); total_bytes += array_sizes[i], i++);
         
          char *mensaje = (char *) malloc (total_bytes);
         
          //Aplicamos un filtro de error que indique un posible overflow
          if(!mensaje){
                       perror("Error al reservar memoria");
                       getch();
          }
          //Aplicamos la copia con la función memcpy
          for(i = bytes_copiados = 0; i < sizeof(array_sizes) / sizeof(int); bytes_copiados += array_sizes[i], i++)
          memcpy(mensaje + bytes_copiados, arrays[i], array_sizes[i]);
         
          //Mostramos el array de almacenaje (mensaje) e introducimos los datos en la cadena final
          cout<<"Estos son los datos enviados:"<<"\n\n";
          //Bucle de asignación de bytes al array de envio
          for(i = 0; i < total_bytes; i++)
               {
               //Mostramos en pantalla el byte
               printf("%d ", (unsigned char) mensaje[i]);
               //Copiamos ese mismo byte en el array de envio
               buf[i]=("%d ", (unsigned char) mensaje[i]);
               }
               
          cout<<"\nTotal de bytes:"<<total_bytes<<"\n";
       
          free(mensaje);
         
          /*Comprobamos que los datos se han transmitido correctamente al array de trabajo buf:
         
          cout<<"\n\nCOMPROBACION\n\n";
          for (i=0; i<531; i++)
              cout<<buf[i]<<" ";
         */
         
         /*
         /////////////////////////////////////////////////////////////////////////////
         ||                                                                         ||
         ||                                                                         ||
         ||          ENVIO DE DATOS AL DISPOSITIVO Y CIERRE DE CONEXIÓN             ||
         ||                                                                         ||
         ||                                                                         ||
         /////////////////////////////////////////////////////////////////////////////
       
         Ahora que ya estamos conectados al servidor,ya podemos enviarle informacion con la funcion (send).
         Este sería el caso de un socket TCP. Al ser un socket UDP, utilizamos la función sendto, que tiene
         una sintaxis distinta. Estos son sus elementos y las diferentes sintaxis de uso de las dos funciones:
           
               send: definicion del socket que creamos en el paso 1
               buf:variable con la informacion a enviar
               Sizeof: Utilizamos el operador sizeof para indicar la longuitud de la variable
               Flag: lo dejamos en 0
         El resultado final:
             
              PARA SEND:
                   send(sock,buf,sizeof(buf),0);
             
              PARA SENDTO:
                   (sock,buf,sizeof(buf),0,(struct sockaddr*)&receiver_addr,sizeof(receiver_addr));

         */
       
             if(sendto(sock,buf,sizeof(buf),0,(struct sockaddr*)&direccion,sizeof(direccion))==-1)
                {//Aplicamos el filtro de error de envio
                printf("ERROR ENVIANDO");
                getch();
                exit(0);
                }
             else
                 {//Confirmamos el éxito del envío
                  closesocket(sock);
                  //puts("\nMensaje enviado, pulsa una tecla para continuar");
                  //getch();
                 }
              };
          }
      };


La parte de la conexión está repetida en las dos funciones porque estas han de ser "autónomas", pero no creo que eso tenga que ver con mi problema  :huh:

Gracias por la ayuda.

EI: juntando mensajes.

¿Nadie sabe cual puede ser el problema? Es extraño porque a veces avisa de "error" en cosas que parecen iguales (el uso de la variable valor dentro de una función, cuando valor ha sido declarado al declarar la función, hay sitios donde no da error y otros donde dice que valor no ha sido declarado, dentro de la función, un par de lineas más abajo de donde lo ha usado sin problema alguno!) o incluso en el uso de sentencias for, closesocket, system...

He intentado jugando con los espacios, añadiendo ; al final de los for (cosa que no es necesaria, al menos en Dev-C++) por descartar, pero los problemas siguen ahí. ¿Quizá esten mal declaradas las librerías? ¿La sintaxis es menos transigente en Visual Studio con el tema de espacios, o me falta algo importante?

Agradecería mucho un poco de ayuda, porque con este problema estoy muy estancado  :huh:

Gracias y un saludo. :laugh:
#3
Hola foreros. Estoy intentando portar unas funciones que escribí en dev-c++ y funcionan correctamente a Visual Studio 2010. Me tira problemas por todos lados cuando porto el programa, con cosas como las llamadas system e incluso declaraciones como los for. En total, un código de algo mas de 500 líneas me lanza 64 errores, una barbaridad, y son todos del estilo de:

"Intellisense: Se esperaba una declaración"
"Intellisense: Se esperaba )"
"intellisense: "IMoaUnknownVtbl" no está definido"

Me llega a tirar errores incluso cuando intento usar variables declaradas en una función, diciendome que no están declaradas.

Nunca he usado Visual Studio y no se si tengo que incluir alguna librería o configurar el editor para que me interprete correctamente el código. ¿Alguna ayuda?

Gracias, un saludo ;)
#4
He seguido dándole vueltas y he cambiado algunas cosas sobre los valores. He puesto un escape para que cuando alcanza el valor tope del rango salga y no se vuelva majara el bucle, y he conseguido que según la duración salte valores o los repita (fijándome en el progreso de valores[canal-1] en comparación con el de secuencia[0], que siempre es fijo).

Pero los valores que quita o añade al rango para ajustarlo siguen siendo muy pocos con lo que la rampa sigue durando una barbaridad.

Copio el código con los arreglos que he hecho hasta ahora:


int rampa(int canal, int valor_a, int valor_b, int duracion)                 //Función de rampa para un canal
       {
       int i;
       bool rampa_ascendente;
       if ((canal<1) || (canal>512) || (valor_a<0) || (valor_b>255) || (valor_b>255) || (duracion<1))
          {
          system("cls");
          cout<<"ERROR - Numero de canal o valor indicado fuera de rango\nPulsa cualquier tecla para continuar...";
          getch();
          return 1;
          }
       else
           {
           int i, j, k, cont, cont_b, intervalo, valores_segundo_sin, valores_segundo_fijo, resta, resta_cont;
           if (valor_a<valor_b)                                                 //Intervalo de valores de la rampa
              {
              rampa_ascendente=true;                                            //Comprobamos si la rampa es ascendente o no
              intervalo=valor_b-valor_a;                                           
              }
           else
               {
               rampa_ascendente=false;
               intervalo=valor_a-valor_b;
               }
           
           valores_segundo_sin=intervalo / duracion;                            //numero de valores por segundo sin reducir a 25/s
           valores_segundo_fijo=25;                                             //numero de valores por segundo fijos
           resta=valores_segundo_sin - valores_segundo_fijo;                    //numero de valores a eliminar en un segundo
           cont=valor_a;                                                        //asignamos al contador el valor de inicio
           resta_cont=valores_segundo_fijo / resta;                             //Cada cuantos valores se elimina uno en un segundo
           //Positivamos los valores resta para poder trabajar con ellos
           if (resta_cont<0)
              {
              //Aqui la variacion de añadir o quitar IMPORTANTE
              resta_cont=resta_cont*(-1);
              }
           if (resta<0)
              {
              resta=resta*(-1);
              }
           
           //ARRAY DE VALORES DE CANALES
           char valores[526];
           for (k=0; k<526; k++)
              {
              valores[k]=0;
              }
           //ARRAY DE SECUENCIA
           char secuencia[1];
           secuencia[0]=0;
           
           //for (j=0; j<duracion; j++)//Este bucle dura la cantidad de segundos que se han ordenado
           j=0;
           cont=valor_a;
           cont_b=0;
           while ((j < duracion) || (cont != intervalo))
               {
               for (i=0; i<valores_segundo_fijo; i++)//Este bucle dura exactamente 1 segundo y contiene 25 repeticiones
                   {
                   if (cont!=intervalo)//Escape en caso de superar el valor final de la rampa
                      {i=valores_segundo_fijo;}
                   //Esta sería la secuencia de contadores y el envio para rampas ascendentes
                   if (rampa_ascendente==true)
                      {     
                       valores[canal-1]=cont;
                       secuencia[0]=secuencia[0]+1;
                       cont++;
                       cont_b++;
                       conectar(valores, secuencia);
                       if (cont_b==resta)
                          {
                          cont=cont++;
                          cont_b=0;
                          }
                       if (secuencia[0]==255)
                          {
                          secuencia[0]=0;
                          }
                       Sleep(10);
                       }
                   else
                   //Esta sería la secuencia de contadores y el envio para rampas descendentes
                       {
                       valores[canal-1]=cont;
                       secuencia[0]=secuencia[0]+1;
                       cont--;
                       cont_b++;
                       conectar(valores, secuencia);
                       if (cont_b==resta_cont)
                          {
                          cont--;
                          cont_b=0;
                          }
                       if (secuencia[0]==255)
                          {
                          secuencia[0]=0;
                          }
                       Sleep(10);
                       }                                             
                   }
               j++;
               }
           return 0;
           }
       };


Gracias por vuestro tiempo  ;D
#5
Gracias por la idea, no es mala idea el timer que dices, toma el tiempo del sistema así que supongo que es más estable que el sleep, que hasta donde se es un contador.

Pero mi mayor problema es el de los valores. Es un puzzle de miedo, obtener la cantidad de paquetes que hay que sustraer o añadir en un segundo para que de 25/s es fácil. Eliminarlos o duplicarlos, una vez que sabes cuantos son, me está volviendo loco. No se que hago mal pero he probado con varios planteamientos, jugando con los bucles y las operaciones con los contadores, pero no me funciona. Lo que más se le ha acercado es el código que he copiado en el primer mensaje y solo consigo llegar a un tercio de los valores, la rampa dura muchísimo mas de lo que tendría que durar, y si lo intento con rangos de valores pequeños ya es para morirse de risa.

Me estoy volviendo loco con esto. Con lo feliz que era yo programando web... :(

Alguna idea para el tema de los valores?
#6
Buenas gente. Tengo un pequeño problema lógico que me está rompiendo el cráneo.

He creado una función que recibe una serie de datos (canal, valor de inicio, valor final, duración) y con un bucle anidado envía los datos a otra función. El bucle anidado está pensado para seguir un intervalo regular, el bucle interior se repite 25 veces en un segundo, y el exterior se repite en función del número de segundos que quiera que dure el envío, y ese dato en segundos es el que le envio a la función.

La gracia está en que el número de envíos por segundo tiene que ser constante, 25 por segundo, pero el rango de valores (valor final - valor de inicio) puede ser cualquiera. Eso significa que tengo que repetir valores o quitarlos para que ajuste a esos 25 valores por segundo, de manera escalonada y continua (no puedo eliminar los valores sobrantes de golpe al principio o al final).

La sucesión de datos, para que lo entendáis, es para subir o bajar la cantidad de luz que un dimmer le entrega a un foco. Envia el dato cada vez que el bucle interior cumple un ciclo a la función conectar.

Os copio la función para que veais el lio que he montado:


int rampa(int canal, int valor_a, int valor_b, int duracion)                 //Función de rampa para un canal
       {
       int i;
       if ((canal<1) || (canal>512) || (valor_a<0) || (valor_b>255) || (valor_b<valor_a) || (valor_b>255) || (duracion<1))
          {
          system("cls");
          cout<<"ERROR - Numero de canal o valor indicado fuera de rango\nPulsa cualquier tecla para continuar...";
          getch();
          return 1;
          }
       else
           {
           int i, j, k, cont, cont_b=0, intervalo, valores_segundo_sin, valores_segundo_fijo, resta, resta_cont;
           intervalo=valor_b-valor_a;                                           //Intervalo de valores de la rampa
           valores_segundo_sin=intervalo/duracion;                              //numero de valores por segundo sin reducir a 25/s
           valores_segundo_fijo=25;                                             //numero de valores por segundo fijos
           resta=valores_segundo_sin - valores_segundo_fijo;                    //numero de valores a eliminar en un segundo
           cont=valor_a;                                                        //asignamos al contador el valor de inicio
           resta_cont=valores_segundo_sin/valores_segundo_fijo;                   //Cada cuantos valores se elimina uno en un segundo
           //Positivamos los valores resta para poder trabajar con ellos
           if (resta_cont<0)
              {
              //Aqui la variacion de añadir o quitar IMPORTANTE
              resta=resta*(-1);
              }
           if (resta<0)
              {
              resta=resta*(-1);
              }
           
           //ARRAY DE VALORES DE CANALES
           char valores[526];
           for (k=0; k<526; k++)
              {
              valores[k]=0;
              }
           //ARRAY DE SECUENCIA
           char secuencia[1];
           
           for (j=0; j<duracion; j++)//Este bucle dura la cantidad de segundos que se han ordenado
               {
               for (i=0; i<25; i++)//Este bucle dura exactamente 1 segundo y contiene 25 repeticiones
                   {
                   valores[canal-1]=cont;
                   secuencia[0]=secuencia[0]+1;
                   cont++;
                   cont_b++;
                   if (cont_b==resta_cont)
                      {
                      cont++;
                      cont_b=0;
                      }
                   if (secuencia[0]==255)
                      {
                      secuencia[0]=0;
                      }
                   conectar(valores, secuencia);

                   Sleep(40); //Pausa en ms para que el bucle dure 1s (1000ms / 25= 40ms)
                   }
               }
           return 0;
           }
       };


Me da dos problemas principalmente. El primero es que no recorre todo el rango de valores que le pido. Si le digo que vaya de 0 a 255, solo llega a enviar un tercio de los valores.

El segundo problema es que no cumple la pausa de 40ms. O no está bien especificado. Porque tarda muuuuuuuuuuuuuuuuuuuuuucho mas de los segundos que le especifico.

¿Debería enfocarlo todo de otra manera? ¿Que hago mal?

Gracias por la ayuda  :D
#7
Solucioné el problema. Estaba llamando a la declaración IP cuando tenía que llamar a dirección,  con lo que la línea terminaba así:

sendto (Descriptor, (char *)&buffer, sizeof(buffer), 0, (struct sockaddr *)&Cliente, longitudCliente);

Muchas gracias por la ayuda. Si alguien necesita el código o tiene las mismas dudas que yo, espero que esto pueda servirle.

Un saludo!
#8
El error que me da el sendto es -1. 

Estoy respetando la estructura del sendto, que hasta donde he investigado es:


sendto (Descriptor, (char *)&buffer, sizeof(buffer), 0, (struct sockaddr *)&Cliente, longitudCliente);

El código que yo he usado es

sendto(sock,buf,sizeof(buf),0,(struct sockaddr*)&ip,sizeof(ip))

Entiendo que el descriptor es sock, buf es la cadena que envío, luego el tamaño de la misma, el cero que he visto en todas las descripciones de internet sobre la instrucción, no se muy bien para qué es o qué define. Finalmente la estructura, la dirección de la variable de la IP a la que se conecta y la longitud de esa variable.

Me lanza continuamente error -1 y no se que puedo estar haciendo mal. Me falta algún dato o declarar alguna otra estructura?

Un saludo!
#9
Hasta donde he entendido la sentencia Sendto, el código para mi programa debería ser:


if(sendto(sock,buf,sizeof(buf),0,(struct sockaddr*)&ip,sizeof(ip))==-1)
         {
         printf("ERROR ENVIANDO");
         getch();
         exit(0);
         }
      else
          {
           puts("\n Mensaje enviado,pulsa una tecla para cerrar el cliente");
           getch();
          }


Sin embargo, he intentado corregirlo y no deja de darme error, o bien llevándome a la librería para mostrarme la sentencia, o bien con fallos de otro tipo.

Puedo "encajar" el sendto en mi programa o tengo que reformar mas partes para poder usarlo? Porque por la forma de fallar creo que estoy intentando meter con calzador un parche en el código  :(
#10
Pues mira, no había caido en algo tan obvio como que un socket UDP no tiene sentido usar connect. Todavía soy un n00b  :-[

He hecho los cambios, cambiar el filtro del bind (dejándolo como el del connect, básicamente), he comentado el connect, y... me dice que bindea bien, que crea el socket bien, pero me da error al enviar. Os copio el código con las correcciones oportunas.


#include <conio.h>
#include <stdlib.h>
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <winsock.h>
#define ip "192.168.0.255" //IP del servidor (A la que conectar)

  using namespace std;
  int main()
  { 

  WSADATA wsa; // Winshock
  int sock;//Descriptor del socket.
  struct sockaddr_in direccion; //Datos del servidor a conectar

  WSAStartup(MAKEWORD(2,0),&wsa);
   
  char buf[531];       // Tamaño del mensaje a enviar
  int puerto=6454;     // puerto del servidor a conectar

  if((sock=socket(AF_INET,SOCK_DGRAM,0))==-1 )
     {
     // Creamos el socket mientras creamos el primer filtro de error
     printf("PROBLEMA AL CREAR EL SOCKET");
     getch();
     exit(0);
     }
  else
    {
    direccion.sin_family=AF_INET; // AF_inet con el protocolo UDP (Información en el paso anterior)
    direccion.sin_port=htons(puerto); //Usamos HTONS para transformar el numero de puerto a uno entendible para el socket.
    direccion.sin_addr.s_addr=inet_addr(ip); // Y agregamos la IP
     
  struct sockaddr_in me;
  memset(&me, 0, sizeof(me));
  me.sin_family = AF_INET;
  me.sin_addr.s_addr = htonl(INADDR_ANY);
  me.sin_port = htons(puerto);
 
  if (bind(sock, (struct sockaddr *)&me, sizeof(me))==-1)
    {
    cout<<"Bind failed - error %d",(int)WSAGetLastError();
    }
    else
    {
    puts("Bind OK");
    }
 
  char total[531]; //Variable maestra en la que iremos introduciendo cada sección del paquete ArtNet Originalmente(531)
  char l_total; //Variable para introducir la suma de longitudes de los fragmentos del paquete
  char puntero; //Puntero para las operaciones de concatenación
  char cabecera[8]={65 , 114 , 116 , 45 , 78 , 101 , 116 , 0}; //Cabecera del paquete
  char opcode[2]={0, 80}; // OpCode (Originalmente 0 (El bit bajo primero) y 80)
  char version[2]={0 , 14}; //Indicador de la versión (Originalmente 0 y 14)
  char secuencia[1]={0}; //Originalmente 1
  char phisycal[1]={2}; //Subred. Originalmente 0
  char universo[2]={0 , 0}; //Define el universo en el que vamos a trabajar
  char lon_val[2]={2 , 0}; //Indice de la longitud de valores (Originalmente 2 y 0) 
  char valores[526]={255, 255, 255, 255, 0 , 0 , 0 , 0 , 0 , 0 , //1,10    //Comienza en el byte 19, termina en el byte 526
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //11-20
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //21-30
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //31-40
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //41,50
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //51,60
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //61,70
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //71,80
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //81,90
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //91,100
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //101,110   
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //111-120
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //121-130
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //131-140
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //141,150
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //151,160
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //161,170
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //171,180
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //181,190
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //191,200
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //201,210 
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //211-220
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //221-230
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //231-240
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //241,250
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //251,260
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //261,270
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //271,280
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //281,290
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //291,300
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //301,310   
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //311-320
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //321-330
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //331-340
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //341,350
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //351,360
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //361,370
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //371,380
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //381,390
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //391,400
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //401,410   
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //411-420
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //421-430
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //431-440
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //441,450
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //451,460
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //461,470
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //471,480
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //481,490
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //491,500
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //501,510
                    0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,      //511,520
                    0 , 0 , 0 , 0 , 0 , 0 };                    //521,526                   
 
  const unsigned int array_sizes[] = {sizeof(cabecera) , sizeof(opcode) , sizeof(version) , sizeof(secuencia) , sizeof(phisycal) , sizeof(universo) , sizeof(lon_val) , sizeof(valores)};
 
  char *arrays[] = {
        cabecera,
        opcode,
        version,
        secuencia,
        phisycal,
        universo,
        lon_val,
        (char *) valores};
   
  unsigned int i, bytes_copiados, total_bytes;
   
  for(i = total_bytes = 0; i < sizeof(arrays) / sizeof(char *); total_bytes += array_sizes[i], i++);
   
  char *mensaje = (char *) malloc (total_bytes);
   
  if(!mensaje){
        perror("Error al reservar memoria");
        getch();
        return 0;
  }
   
  for(i = bytes_copiados = 0; i < sizeof(array_sizes) / sizeof(int); bytes_copiados += array_sizes[i], i++)
  memcpy(mensaje + bytes_copiados, arrays[i], array_sizes[i]);
   
  cout<<"Datos del paquete:"<<"\n";
  for(i = 0; i < total_bytes; i++)
        {
        printf("%d ", (unsigned char) mensaje[i]);
        buf[i]=("%d ", (unsigned char) mensaje[i]);
        }
       
  cout<<"\nTotal de bytes:"<<total_bytes<<"\n";
  free(mensaje);
   
   cout<<"\n\nCOMPROBACION\n\n";
   for (i=0; i<531; i++)
       cout<<buf[i]<<" ";

      if(send(sock,buf,sizeof(buf),0)==-1)
         {
         printf("ERROR ENVIANDO");
         getch();
         exit(0);
         }
      else
          {
           puts("\n Mensaje enviado,pulsa una tecla para cerrar el cliente");
           getch();
          }

 

   }
return 0;
}



Más que la solución en si, me gustaría saber qué ha fallado y en qué me he equivocado. Me llama la atención porque en internet todo lo que he encontrado sobre winsock era TCP y no he encontrado un solo listado de un socket UDP completo y funcional.

Gracias por la ayuda  :)