programacion de sockets con C en GNU/Linux

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

programacion de sockets con C en GNU/Linux

Notapor lacabra25 » Mar Mar 17, 2009 6:54 pm

Hola, estoi aprendiendo a programar en C sockets, se que GNU/Linux soporta ademas de IPv4 las IPv6 lo que no estoi seguro de como programar el codigo para que pueda funcionar con ambas IP ya que en el ejemplo que he estado biendo explican como usarlo con IPv4.

El codigo que tengo por el momento es:
Código: Seleccionar todo
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <arpa/inet.h>

int conectar(char *direccion, unsigned short int puerto){
register int r=0;
int descriptor;
struct in_addr direccion_internet;
struct sockaddr_in direccion_socket;
/*pasando la cadena con la IP con los bytes separados por puntos a un numero de 32 bits*/
direccion_internet.s_addr= inet_addr(direccion);
if(direccion_internet.s_addr == -1){
   r= 1;
}else{
   /*rellenando la estructura de la direccion de socket*/
   direccion_socket.sin_family = AF_INET;
   direccion_socket.sin_port = htons(puerto);
   direccion_socket.sin_addr.s_addr= direccion_internet.s_addr;
   memset(&(direccion_socket.sin_zero), '\0', 8);
   /*obteniendo el descriptor de fichero*/
   descriptor= socket(AF_INET, SOCK_STREAM, 0);
   if(descriptor == -1){
      r= 2;
   }else{
      if(connect(descriptor, (struct sockaddr *)&direccion_socket, sizeof(struct sockaddr)) == -1){
         r= 3;
      }
   }
}
if(r != 0){
   return -1;
}else{
   return descriptor;
}
}


Ya he probado la funcion pasandole como direccion la IP de google y no da ningun error, por lo que supongo que conecta bien, lo que no se si al pasarle una IPv6 funcionara bien igualmente o si debo cambiar algo al codigo para poder manejar ambas IP.

Si sabeis de algun manual o tutorial sobre los sockets en C para IPv6 lo agradeceria (y si es para IPv6 e IPv4 lo agradeceria más aun).
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Mar Mar 17, 2009 11:42 pm

No se si habrá libros de lo que tu buscas( espero que si), pero estoy seguro de que habra montones de libros( y muchos de ellos de informatica en una de las siguientes paginas(si esto gusta podria ponerse en tema aparte xD:

knowfree
mailxmail
librosdeluz
free-ebooks
manybooks
www.freeebooks.info

Estos son unos pocos(google+"free ebook"=esto(mas o menos))
Ire editando a medida que encuentre nuevos(le he cogido el gusto a esto del conocimiento de "libre" difusion.

Sobra mencionar que la mayoria(si no todos) estan en ingles, pero es que este es uno de los requerimientos minimos e indispensables en el mundo de los ordenadores e internet xD

Por cierto, tambien existe otra comunidad de habla hispana d desarrollo de juegos en la que quizas puedas encontrar algo(www.vjuegos.org)
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor Adri » Mié Mar 18, 2009 11:03 am

Encontré http://ou800doc.caldera.com/en/SDK_netapi/sockC.TheIPv6sockaddrstructure.html por ahi buscando... espero que te sirva (con utilizar estas estructuras en vez de in_addr y sockaddr_in debería funcionar creo ^^ ).

No entiendo muy bien que hace tu código... cuando haces un connect a una direccion y un puerto tiene que haber un socket escuchando y aceptando conexiones... google tiene un puerto escuchando?? :S

Un saludo
Adri
 
Mensajes: 4
Registrado: Jue Mar 05, 2009 2:42 pm

Notapor lacabra25 » Mié Mar 18, 2009 3:39 pm


Muchas gracias, acabdo de cargarlo en otra pestaña para mirarlo.
Adri escribió:espero que te sirva

Por lo que he estado mirando hasta ahora la pagina (por el momento solo por encima) creo que si me sirve, pero como no conozco un servidor de internet que trabaje ya con IPv6 para probar a conectarme y como aun no he escrito funciones con las que poder hacer un servidor sencillo no puedo estar seguro del resultado
Adri escribió:No entiendo muy bien que hace tu código...

por el momento no son mas que 4 funciones para trabajar con sockets IPv4 y otras 4 para trabajar con sockets IPv6 pero pretendo crear una libreria para el manejo de sockets para IPv6 e IPv4 con funciones suficientes para programar un cliente o un servidor indistintamente sin tener que preocuparse por los sockets y (en el caso de los servidores) por bloqueos y atencion a varios clientes y que de ademas facilidad para empaquetar informacion y enviarla sea del tipo que sea. Con esto pretendo hacer una libreria para hacer juegos en red que sea facil de usar y lo suficiente potente como para que funcione bien en los juegos, antes de comenzar con esto ya sabia de la existencia de SDL_net y he probado esta libreria anteriormente pero aunque pueda facilitar un poco mas la programacion de los sockets y la portabilidad que programarlos tal y como lo estoi haciendo yo ahora hay algunos aspectos que creia que podrian incluir la libreria y no sabia si SDL_net ya estaba preparada para IPv6; por ejemplo para montar un servidor con SDL_net la cuestion de atender a varios servidores debe ser implementada con las funciones que ofrece la biblioteca SDL_net y SDL; otra cosa que no me convencia es que estuviera tan ligada a SDL (en un servidor para partidas en red de un determinado juego no interesa para nada tener SDL ya que no vas a necesitar ni los graficos ni el sonido, como mucho los eventos pero nada mas (y segun creo para usar SDL_net hay que compilar tambien con SDL). Ya que ha salido este tema os informo de que la libreria que estoi programando estara bajo la licencia LGPL y que intentare (una vez la acabe para GNU/Linux) que sea portable por compilacion condicionada.
Adri escribió:cuando haces un connect a una direccion y un puerto tiene que haber un socket escuchando y aceptando conexiones... google tiene un puerto escuchando?? :S

Claro que si, cuando pones en el navegador www.google.es eso es traducido a una IP (el servicio de DNS) y el navegador se conecta a la IP en el puerto 80 y comienza a "entablar una conversacion" con el servidor usando el protocolo HTTP, se pone a la escucha y el servidor le responde (tambien en HTTP) enviandole una respuesta acorde a lo que pidiera el navegador. Normalmente despues se cierra la conexion por como ya ha recibido la pagina y la ha cargado en pantalla. Por el momento creo que tengo algunos problemas con la funcion de DNS para pasar un dominio a su correspondiente direccion IP, este problema lo estoi teniendo en IPv4, ya que cada vez que ejecuto el programa me da que la direccion de google es diferente (lo que no se si podria ser por que google usara un servidor maestro y varios esclavos y por eso me diese diferentes IP en cada vez, despues cuando le envio una cabecera HTTP pidiendole la pagina de google aunque no me da error al enviarla no recivo respuesta lo que supongo que sera por que mando una cabecera HTTP mal mas que por la funcion para conectarse y para enviar y recibir datos (use una cabecera que vi en wikipedia a ver si me devolvia la pagina, de HTTP se poco y nada).
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor Juanxo » Mié Mar 18, 2009 4:32 pm

A mi siempre me sale la misma cuando hago un ping a la direccion www.google.es (209.85.229.99).

Puede ser que a lo mejor obtengas la ip publica(o algo por ese estilo), que cambia cada vez que se conecta??
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor lacabra25 » Mié Mar 18, 2009 5:00 pm

Juanxo escribió:A mi siempre me sale la misma cuando hago un ping a la direccion www.google.es (209.85.229.99).

Puede ser que a lo mejor obtengas la ip publica(o algo por ese estilo), que cambia cada vez que se conecta??


no, no creo, si fuese asi a ti tambien te deberia de cambiar al hacer ping ya que supuestamente el ping usa las mismas funciones que tengo yo que usar para trabajar con los sockets ya que esta en una libreria del sistema (y seguro que el ping las usa mejor que yo jeje). Entonces el problema lo debo de tener en la funcion del DNS.

Os dejo el codigo de la funcion de DNS (tanto la que tengo para IPv4 como para IPv6, pego las dos):

Código: Seleccionar todo
int DNS_IPv4(char *direccion, char *host){
register int r=0;
struct hostent *h;
h=gethostbyname(host)
if(h == NULL){
   r= 1;
}else{
   if(strcpy(direccion, inet_ntoa(*((struct in_addr *)h->h_addr))) == NULL){
      r= 2;
   }
}
return r;
}

int DNS_IPv6(char *direccion, char *host, char *servicio, unsigned long int longitud_d, unsigned long int longitud_s){
register int r=0;
int n;
struct sockaddr_in6 direccion_socket;
struct in6_addr direccion_internet;
r= getnameinfo((struct sockaddr *)&direccion_socket, sizeof(struct sockaddr_in6), host, strlen(host), servicio, longitud_s, NI_NUMERICHOST);
direccion_internet= direccion_socket.sin6_addr;
if(r == 0){
   inet_ntop(AF_INET6, &direccion_internet, direccion, longitud_d);
}
return r;
}


La funcion DNS_IPv6 seguramente es la que mas errores puede tener, pero la DNS_IPv4 tiene algo mal pero no entiendo el que y esta funcion (DNS_IPv4) la escribi con la informacion que encontre en http://www.arrakis.es/~dmrq/beej/ pero hace tiempo que no la actualiza el autor.
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)

Notapor lacabra25 » Jue Mar 19, 2009 4:23 pm

¡Primera prueba del codigo con buenos resultados!
Hoy al fin consegui enviar una cabecera HTTP correcta y recibir respuesta. Al enviar la cabecera para pedir la pagina de google recivi esto:
Código: Seleccionar todo
HTTP/1.1 200 OK
Cache-Control: private, max-age=0
Date: Thu, 19 Mar 2009 16:02:18 GMT
Expires: -1
Content-Type: text/html; charset=ISO-8859-1
Server: gws
Transfer-Encoding: chunked

197a
<html><head><meta><title>Google</title><script>window.google={kEI:"imzCSYChHoW7jAfniuWhCw",kEXPI:"17259",kHL:"en"};
window.google.sn="webhp";window.google.timers={load:{t:{start:(new Date).getTime()}}};try{window.google.pt=window.gtbExternal&&window.gtbExternal.pageT()||window.external&&window.external.pageT}catch(b){}
window.google.jsrt_kill=1;
var _gjwl=location;function _gjuc(){var a=_gjwl.hash;if(a.indexOf("&q=")>0||a.indexOf("#q=")>=0){a=a.substring(1);if(a.indexOf("#")==-1){for(var c=0;c<a.length;){var d=c;if(a.charAt(d)=="&")++d;var b=a.indexOf("&",d);if(b==-1)b=a.length;var e=a.substring(d,b);if(e.indexOf("fp=")==0){a=a.substring(0,c)+a.substring(b,a.length);b=c}else if(e=="cad=h")return 0;c=b}_gjwl.href="search?"+a+"&cad=h";return 1}}return 0}function _gjp(){!(window._gjwl.hash&&window._gjuc())&&setTimeout(_gjp,500)};
window._gjp && _gjp();</script><style>body,td,a,p,.h{font-family:arial,sans-serif}.h{color:#36c;font-size:20px}.q{color:#00c}.ts td{padding:0}.ts{border-collapse:collapse}#gbar{height:22px;padding-left:2px}.gbh,.gbd{border-top:1px solid #c9d7f1;font-size:1px}.gbh{height:0;position:absolute;top:24px;width:100%}#gbi,#

Y los que conozcais el XHTML (o el HTML) ya os habreis dado cuenta de que es la pagina de google, por lo que he conseguido conectarme al servidor de google, lo unico que no termino de entender es por que cada vez que ejecuto el programa para probar el codigo me dice que la IP de google es una diferente. Probe a hacer ping a google.es varias veces y en cada vez que ejecuto ping me da tambien una IP distinta por lo que supongo que la funcion que se encarga de transformar el host en una IP debe de estar bien. En cuanto a la funcion de DNS para IPv6 por el momento solo puedo suponer que el servidor de google no esta trabajando con IPv6 por el momento ya que al compilar no recivo errores y la he echo siguiendo distintas referencias que he ido encontrando por la web pero al intentar ver la IPv6 del google el programa me muestra diferentes cosas (al iguar que me aparece cada vez con diferente IPv4) como /チ�� y como no se de ningun servidor HTTP que ya este trabajando con IPv6 pues no puedo poner a prueba las funciones para IPv6.

Os informare segun avance el codigo de la libreria que estoi escribiendo. Ahora que ya se que por lo menos las funciones para IPv4 funcionan puedo continuar programando mas funciones, y ya encontrare la forma de probar las funciones de IPv6, ¿alguien sabe de algun servidor web que trabaje con IPv6?, estoi pensando de hacer una funcion para DNS independiente de si es IPv6 o IPv4 que primero intente obtener la IPv6 y si no lo consigue (por que el servidor trabaje solo con IPv4 y no admita trabajar con IPv6) lo intente con la funcion de IPv4.

Si sabeis de algun tutorial sobre sockets en C con IPv6 aun estoi interesado para poder comprobar si el codigo que tengo por ahora para IPv6 en principio estaria bien, o si esta mal. Si teneis suugerencias para la libreria son bien recividas, por el momento estoi pensando en lo que ya he comentado de hacer una funcion DNS tanto para IPv6 como para IPv4 y si consiguiese unir las funciones de conectar, desconectar, enviar datos y recivirlos pues tambien estaria bien, añadir funciones para los sockets UDP (por ahora solo tengo las funciones para los sockets TCP) y añadir funciones para poder funcionar como servidor y algo de hilos para atender a varios clientes a la vez y alguna forma de evitar los bloqueos de las funciones que tienen esta caracteristica.

EDITO:
Hola, ya tengo todas las funciones necesarias para usar sockets TCP/IPv4, TCP/IPv6, UDP/IPv4, UDP/IPv6, DNS IPv4, DNS IPv6 y conjuntos de sockets para no quedarse bloqueado en las funciones de recepcion de datos, ahora estoi intentando añadir sockets raw pero por lo que he estado mirando por diversos resultados de google no me queda del todo claro el trabajo con este tipo de sockets ¿sabeis algo de estos sockets o de algun manual o tutorial?
Esta cuenta ahora a pasado a la cuenta jhg
Avatar de Usuario
lacabra25
 
Mensajes: 222
Registrado: Mié Abr 02, 2008 9:45 pm
Ubicación: Tenerife (España)


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado