• Lunes 29 de Abril de 2024, 11:34

Autor Tema:  Sockets Udp  (Leído 2547 veces)

kezern

  • Miembro activo
  • **
  • Mensajes: 26
    • Ver Perfil
Sockets Udp
« en: Miércoles 29 de Noviembre de 2006, 16:41 »
0
Hola a todos. He hecho un programa servidor que envia una imagen a otro programa cliente usando sockets TCP. Me gustaría cambiarlo para que en lugar de TCP usase UDP. Lo he intentado pero no consigo que funcione.
El programa servidor es así.
Código: Text
  1.  
  2.   // Initiate the winsock2 library
  3.   WORD wVersionRequested;  
  4.   WSADATA wsaData;
  5.   wVersionRequested=MAKEWORD(2,2);
  6.   if (WSAStartup(wVersionRequested,&wsaData)!=0) {
  7.     printf("Initiating error");
  8.     exit(1);
  9.   }
  10.   //Definition of local and remote socket addresses
  11.   localSocketAddress.sin_family=AF_INET;
  12.   localSocketAddress.sin_port=htons(7777);
  13.   localSocketAddress.sin_addr.s_addr=htonl(INADDR_ANY);
  14.   remoteSocketAddress.sin_family=AF_INET;
  15.   remoteSocketAddress.sin_port=htons(7777);
  16.   remoteSocketAddress.sin_addr.s_addr=inet_addr("192.168.0.2");
  17.  
  18.   // TCP sockets  
  19.   sock=socket(PF_INET,SOCK_STREAM,0);
  20.   if(sock==INVALID_SOCKET) {
  21.     printf("Creating socket error");
  22.     exit(1);
  23.   }
  24.   //Configuro los parámetros del socket
  25.   int val=5*1024*4;
  26.   int size=sizeof(int);
  27.   int flag=1;
  28.   setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char *) &val, sizeof(val));
  29.   setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (const char *) &val, sizeof(val));
  30.   setsockopt(sock,IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
  31.  
  32.   unsigned long iostate = 1;
  33.   ioctlsocket(dialogSock,FIONBIO, &iostate); //non-blocking mode enabled
  34.  
  35.   int  check=bind(sock,(sockaddr*)&localSocketAddress,sizeof(localSocketAddress));
  36.   if(check==SOCKET_ERROR) {
  37.     printf("Bind error");
  38.     exit(1);
  39.   }
  40.   while (0!=listen(sock,0)){}
  41.   dialogSock=accept(sock,(struct sockaddr*)0, 0);
  42.   if(dialogSock==SOCKET_ERROR) {
  43.     printf("Accept error");
  44.     exit(1);
  45.   }
  46.   char buffers[80];
  47.   memset(buffers, 0, sizeof(buffers)); //Clear the buffer
  48.         d=getJPG();
  49.         sprintf(buffers, "%8d", d->tam);
  50.   send(dialogSock, buffers, sizeof(buffers) - 1,0);
  51.   send(dialogSock, (const char*)d->buffer,d->tam,0);
  52.  
  53.  

Y el cliente así:
Código: Text
  1.  
  2. // Initiate the winsock2 library
  3.   WORD wVersionRequested;  
  4.   WSADATA wsaData;
  5.   wVersionRequested=MAKEWORD(2,2);
  6.   if (WSAStartup(wVersionRequested,&wsaData)!=0) {
  7.     printf("Initiating error");
  8.     exit(1);
  9.   }
  10.  
  11.   //Definition of local and remote socket addresses
  12.   localSocketAddress.sin_family=AF_INET;
  13.   localSocketAddress.sin_port=htons(7777);
  14.   localSocketAddress.sin_addr.s_addr=htonl(INADDR_ANY);
  15.   remoteSocketAddress.sin_family=AF_INET;
  16.   remoteSocketAddress.sin_port=htons(7777);
  17.   remoteSocketAddress.sin_addr.s_addr=inet_addr("192.168.0.3");
  18.  
  19.   // TCP sockets, creo los dos sockets  
  20.   sock=socket(PF_INET,SOCK_STREAM,0);
  21.   if(sock==INVALID_SOCKET) {
  22.     printf("Creating socket error");
  23.     exit(1);
  24.   }
  25.  
  26.   //Configuro cada uno de los sockets
  27.   int val=5*1024*4;
  28.   int size=sizeof(int);
  29.   int flag=1;
  30.   setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char *) &val, sizeof(val));
  31.   setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (const char *) &val, sizeof(val));
  32.   setsockopt(sock,IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
  33.  
  34.   //Conecto los dos sockets
  35.   int  check=connect(sock, (struct sockaddr*) &remoteSocketAddress, sizeof remoteSocketAddress);
  36. check=recv (sock, buffers, sizeof(buffers)-1, 0);
  37.   int num=atoi(buffers);
  38.   char* buf;
  39.   buf=new char [num];
  40.   check=recv (sock,buf,num,0);
  41.   mf.size=num;
  42.   mf.data=(unsigned char*)buf;
  43.  
  44.  
Lo que he hecho ha sido cambiar el SOCK_STREAM por SOCK_DGRAM y eliminar en el servidor las funciones bind, listen y connect además de cambiar los send por sendto.
Pero no me funciona.
¿Alguien puede echarme una mano?

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Sockets Udp
« Respuesta #1 en: Miércoles 29 de Noviembre de 2006, 16:56 »
0
No mire el codigo sino lo que comentabas. ¿Cambiaste tambien recv por recvfrom?

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.

kezern

  • Miembro activo
  • **
  • Mensajes: 26
    • Ver Perfil
Re: Sockets Udp
« Respuesta #2 en: Miércoles 29 de Noviembre de 2006, 17:01 »
0
Creo que si que lo he cambiado bien. He añadido las estructuras en las que tengo las direcciones y los puertos. Me extraña que en caso del cliente sea NULL pero así lo encontré en el manual que he usado.
El send es así
Código: Text
  1.  
  2. send(sock, buffers, sizeof(buffers) - 1,0);
  3. send(sock, (const char*)d->buffer,d->tam,0);
  4.  
  5.  
Que lo he cambiado por
Código: Text
  1.  
  2. sendto(sock, buffers, sizeof(buffers) - 1,0, (struct sockaddr *) &remoteSocketAddress, sizeof remoteSocketAddress);
  3. sendto(sock, (const char*)d->buffer,d->tam,0, (struct sockaddr *) &remoteSocketAddress, sizeof remoteSocketAddress);
  4.  
  5.  

Y en el caso del recv
Código: Text
  1.  
  2. check=recv (sock, buffers, sizeof(buffers)-1, 0);
  3. check=recv (sock,buf,num,0);
  4.  
  5.  
Y el recvfrom
Código: Text
  1.  
  2. recvfrom (socky, buffers, sizeof(buffers)-1, 0, (struct sockaddr *)NULL, &lon2);
  3. check=recvfrom (socky,buf,num,0, (struct sockaddr *)NULL, &lon2);
  4.  
  5.  
He añadido la estructuras de direcciones tal y como sale en un manual que tengo

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Sockets Udp
« Respuesta #3 en: Miércoles 29 de Noviembre de 2006, 18:25 »
0
El bind no tenes que eliminarlo.

Puede ser que estos ejemplos te ayuden:
http://pont.net/socket/

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.

kezern

  • Miembro activo
  • **
  • Mensajes: 26
    • Ver Perfil
Re: Sockets Udp
« Respuesta #4 en: Miércoles 29 de Noviembre de 2006, 19:52 »
0
Muchas gracias por tu ayuda. Ahora estoy en casa. Mañana en el trabajo intentaré a ver si consigo algo.
La página de ejemplos que has puesto al parecer son en Unix, supongo que no hay diferencia entre Unix y windows no?
Un saludo.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Sockets Udp
« Respuesta #5 en: Miércoles 29 de Noviembre de 2006, 20:12 »
0
Cita de: "kezern"
Muchas gracias por tu ayuda. Ahora estoy en casa. Mañana en el trabajo intentaré a ver si consigo algo.
La página de ejemplos que has puesto al parecer son en Unix, supongo que no hay diferencia entre Unix y windows no?
Un saludo.
Practicamente nada, Winsock necesita la inicializacion (que ya tenes) y provee mas funciones pero todas las standard las soporta.

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.

kezern

  • Miembro activo
  • **
  • Mensajes: 26
    • Ver Perfil
Re: Sockets Udp
« Respuesta #6 en: Jueves 30 de Noviembre de 2006, 09:32 »
0
Nada, he puesto el bind tanto en el cliente como en el servidor y no funciona. Pego aquí debajo los dos programas completos. Lo que hace el servidor al ejecutar la función OnIniciar() es preparar el socket y pasar el apuntador al socket como parámetro a un thread. En ese thread comprimo la imagen y la mando. El cliente hace algo parecido. La función prepara el socket y lanza el thread pasándole como parametro el puntero al socket. Recoge la imagen y la muestra por pantalla. Pero el problema que tengo es que la pantalla de cliente sale negra. No se si porque no envia o porque no recibe. Intento pasarle el debug pero me dice que el breakpoint está puesto incorrectamente y lo desactiva.

El servidor es:
Código: Text
  1.  
  2. UINT WINAPI threaded(LPVOID param)
  3.  
  4. {
  5.   void **tmp = (void **) param;
  6.   SOCKET sock = (SOCKET) tmp[0];
  7.  
  8.   //Se conecta un cliente
  9.  
  10.   char buffers[80];
  11.   memset(buffers, 0, sizeof(buffers)); //Clear the buffer
  12.  
  13.   while (true)
  14.   {    
  15.       ///Creo un bucle para verificar que la función devuelve cierto.
  16.       while (!WriteRGBBytesIntoJpegFile(240,320,15,(unsigned char*) tmp[1])){}
  17.       //Almaceno la imagen y el tamaño en la estructura d
  18.       d=getJPG();
  19.       sprintf(buffers, "%8d", d->tam);
  20.       sendto(sock, buffers, sizeof(buffers) - 1,0, (struct sockaddr *) &remoteSocketAddress, sizeof remoteSocketAddress);
  21.       sendto(sock, (const char*)d->buffer,d->tam,0, (struct sockaddr *) &remoteSocketAddress, sizeof remoteSocketAddress);
  22.       proceso->SuspendThread();
  23.   }
  24.   ExitThread(0);
  25.   return 0;
  26.  
  27. }
  28.  
  29. void CARToolkitPPCDlg::OnIniciar()
  30. {
  31.   m_renderizar=true;
  32.   render->ShowWindow(true);
  33.   render->SetFocus();
  34.   GXResume();
  35.   render->SetForegroundWindow();    
  36.   int res=SHFullScreen(render->m_hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);    
  37.   //activamos el timer de renderizado
  38.   SetTimer(1,10,0);
  39.   SetTimer(2,400,0);
  40.  
  41.   ///Sockets a pelo
  42.   // Initiate the winsock2 library
  43.   WORD wVersionRequested;  
  44.   WSADATA wsaData;
  45.   wVersionRequested=MAKEWORD(2,2);
  46.   if (WSAStartup(wVersionRequested,&wsaData)!=0) {
  47.     printf("Initiating error");
  48.     exit(1);
  49.   }
  50.   //Definition of local and remote socket addresses
  51.   localSocketAddress.sin_family=AF_INET;
  52.   localSocketAddress.sin_port=htons((u_short)m_local_port);
  53.   localSocketAddress.sin_addr.s_addr=htonl(INADDR_ANY);
  54.   remoteSocketAddress.sin_family=AF_INET;
  55.   //remoteSocketAddress.sin_port=htons(7777);
  56.   remoteSocketAddress.sin_port=htons((u_short)m_remote_port);
  57.   // Here it's the remote machine ip address
  58.   int nSize = m_ip.GetLength();
  59.   char *pAnsiString = new char[nSize+1];
  60.   memset(pAnsiString,0,nSize+1);
  61.   wcstombs(pAnsiString, m_ip, nSize+1);
  62.   remoteSocketAddress.sin_addr.s_addr=inet_addr(pAnsiString);
  63.  
  64.   // TCP sockets  
  65.   sock=socket(PF_INET,SOCK_DGRAM,0);
  66.   if(sock==INVALID_SOCKET) {
  67.     printf("Creating socket error");
  68.     exit(1);
  69.   }
  70.   //Configuro los parámetros del socket
  71.   int val=5*1024*4;
  72.   int size=sizeof(int);
  73.   int flag=1;
  74.   setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char *) &val, sizeof(val));
  75.   setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (const char *) &val, sizeof(val));
  76.   setsockopt(sock,IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
  77.  
  78.   int  check=bind(sock,(sockaddr*)&localSocketAddress,sizeof(localSocketAddress));
  79.  
  80.   /*unsigned long iostate = 1;
  81.   ioctlsocket(dialogSock,FIONBIO, &iostate); //non-blocking mode enabled
  82.  
  83.   int  check=bind(sock,(sockaddr*)&localSocketAddress,sizeof(localSocketAddress));
  84.   if(check==SOCKET_ERROR) {
  85.     printf("Bind error");
  86.     exit(1);
  87.   }
  88.   while (0!=listen(sock,0)){}
  89.   dialogSock=accept(sock,(struct sockaddr*)0, 0);
  90.   if(dialogSock==SOCKET_ERROR) {
  91.     printf("Accept error");
  92.     exit(1);
  93.   }*/
  94.   ///Fin de sockets a pelo*/
  95.   void **tmp = new void*[2];
  96.   tmp[0]=(void *)sock;
  97.   tmp[1]=app->getConvertedData();
  98.   proceso = AfxBeginThread(threaded,(void*)tmp,THREAD_PRIORITY_NORMAL,0,0,NULL);
  99. }
  100.  
  101.  
Y el cliente
Código: Text
  1.  
  2. UINT WINAPI threaded(LPVOID param)
  3.  
  4. {
  5.   void **tmp = (void **) param;
  6.   SOCKET socky = (SOCKET) tmp[0];
  7.   //Se conecta un cliente
  8.   bind (sock, (struct sockaddr *) &remoteSocketAddress, sizeof remoteSocketAddress);
  9.   int length = sizeof remoteSocketAddress;
  10.   getsockname (sock, (struct sockaddr *) &remoteSocketAddress, &length);
  11.   char buffers[80];
  12.   memset(buffers, 0, sizeof(buffers)); //Clear the buffer
  13.   bool cycle=true;
  14.   int check, lon2;
  15.   while (cycle)
  16.   {
  17.     check=recvfrom (socky, buffers, sizeof(buffers)-1, 0, (struct sockaddr *)NULL, &lon2);
  18.     int num=atoi(buffers);
  19.     char* buf;
  20.     buf=new char [num];
  21.     check=recvfrom (socky,buf,num,0, (struct sockaddr *)NULL, &lon2);
  22.     mf.size=num;
  23.     mf.data=(unsigned char*)buf;
  24.     render.SetFocus();
  25.     app->renderFrame(mf);
  26.   }
  27.   ExitThread(0);
  28.   return 0;
  29.  
  30. }
  31.  
  32. void CARToolkitPPCDlg::OnIniciar()
  33. {
  34.   m_renderizar=true;
  35.   bool cycle = true;
  36.   render->ShowWindow(true);
  37.   render->SetFocus();
  38.   GXResume();
  39.   render->SetForegroundWindow();    
  40.   int res=SHFullScreen(render->m_hWnd, SHFS_HIDETASKBAR | SHFS_HIDESIPBUTTON | SHFS_HIDESTARTICON);    
  41.   int numUsers=0;
  42.   //conexión desde el servidor
  43. //  socketClient= new GeneralSocket(file);
  44.  
  45.   ///Conexión de los sockets a pelo
  46.   // Initiate the winsock2 library
  47.   WORD wVersionRequested;  
  48.   WSADATA wsaData;
  49.   wVersionRequested=MAKEWORD(2,2);
  50.   if (WSAStartup(wVersionRequested,&wsaData)!=0) {
  51.     printf("Initiating error");
  52.     exit(1);
  53.   }
  54.  
  55.   //Definition of local and remote socket addresses
  56.   localSocketAddress.sin_family=AF_INET;
  57.   localSocketAddress.sin_port=htons((u_short)m_local_port);
  58.   localSocketAddress.sin_addr.s_addr=htonl(INADDR_ANY);
  59.   remoteSocketAddress.sin_family=AF_INET;
  60.   remoteSocketAddress.sin_port=htons((u_short)m_remote_port);
  61.   // Here it's the remote machine ip address
  62.   int nSize = m_ip.GetLength();
  63.   char *pAnsiString = new char[nSize+1];
  64.   memset(pAnsiString,0,nSize+1);
  65.   wcstombs(pAnsiString, m_ip, nSize+1);
  66.   remoteSocketAddress.sin_addr.s_addr=inet_addr(pAnsiString);
  67.  
  68.   // TCP sockets, creo los dos sockets  
  69.   sock=socket(PF_INET,SOCK_DGRAM,0);
  70.   if(sock==INVALID_SOCKET) {
  71.     printf("Creating socket error");
  72.     exit(1);
  73.   }
  74.  
  75.   //Configuro cada uno de los sockets
  76.   int val=5*1024*4;
  77.   int size=sizeof(int);
  78.   int flag=1;
  79.   setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (const char *) &val, sizeof(val));
  80.   setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (const char *) &val, sizeof(val));
  81.   setsockopt(sock,IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
  82.  
  83.   bind(sock, (struct sockaddr *) &remoteSocketAddress, sizeof(remoteSocketAddress));
  84.   //unsigned long iostate = 1;
  85.   //ioctlsocket(sock,FIONBIO, &iostate); /*non-blocking mode enabled*/
  86.  
  87.   //Conecto los dos sockets
  88.   //int  check=connect(sock, (struct sockaddr*) &remoteSocketAddress, sizeof remoteSocketAddress);
  89.   ///Fin de los sockets a pelo*/
  90.   void **tmp = new void*[2];
  91.   tmp[0]=(void *)sock;
  92.   tmp[1]=(void *)app;
  93.   proceso = AfxBeginThread(threaded,(void*)tmp,THREAD_PRIORITY_NORMAL,0,0,NULL);
  94.  
  95.  
  96.  
  97. }
  98.  
  99.  

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Sockets Udp
« Respuesta #7 en: Jueves 30 de Noviembre de 2006, 09:55 »
0
¿Viste los ejemplos? No tenes que usar ni listen, ni accept ni connect para nada.

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.

kezern

  • Miembro activo
  • **
  • Mensajes: 26
    • Ver Perfil
Re: Sockets Udp
« Respuesta #8 en: Jueves 30 de Noviembre de 2006, 09:58 »
0
Si que he mirado los ejemplos. No los estoy usando (ninguna de las tres fuciones). Si miras en el codigo verás que están comentados.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Sockets Udp
« Respuesta #9 en: Jueves 30 de Noviembre de 2006, 10:08 »
0
No voy a ponerme a ver un extracto de codigo de MFC, no tengo tiempo. Pero acabo de poner tu mismo codigo de inicializacion, cambiado las cabeceras de los ejemplos (windows.h y winsock.h) y reemplazado el close por closesocket y funcionan perfectamente bajo Windows.

PD. El cliente recibe y el servidor envia ... como se entera el servidor quien tiene que recibir y cuando ...

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.

kezern

  • Miembro activo
  • **
  • Mensajes: 26
    • Ver Perfil
Re: Sockets Udp
« Respuesta #10 en: Jueves 30 de Noviembre de 2006, 12:00 »
0
No entiendo lo que dices de como se entera el servidor de quien tiene que recibir...
El servidor manda el dato a un único cliente que tiene una ip ya conocida.
Dices que has usado mi mismo código de inicialización. ¿Entonces que estoy haciendo mal?

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Sockets Udp
« Respuesta #11 en: Jueves 30 de Noviembre de 2006, 12:28 »
0
¿Como sabe el servidor que tiene que enviar los datos? Antes usabas listen, accept y entonces sabias que se habia producido una conexion. ¿Ahora? Si el cliente solo recibe como se entera el servidor de que esta el cliente esperando sus mensajes.

Lo normal es que el cliente envie algo para que el servidor se entere de su existencia y despues le responda.

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.

kezern

  • Miembro activo
  • **
  • Mensajes: 26
    • Ver Perfil
Re: Sockets Udp
« Respuesta #12 en: Jueves 30 de Noviembre de 2006, 12:30 »
0
Pues la verdad es que no había controlado eso. El servidor simplemente se iniciaba y comenzaba a enviar datos. Después el cliente los recoge. Me da igual si se pierden datos al prinicipio, mientras el cliente aún no está preparado para recibir.

Eternal Idol

  • Moderador
  • ******
  • Mensajes: 4696
  • Nacionalidad: ar
    • Ver Perfil
Re: Sockets Udp
« Respuesta #13 en: Jueves 30 de Noviembre de 2006, 12:55 »
0
¿Seguro te da igual? Por algo no ves la imagen correcta ... sino sabes depurarlo al menos pone algunos OutputDebugString (los podes ver con el DebugView por ejemplo) para confirmar que los datos son enviados/recibidos.

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.