Article View: es.comp.os.linux.programacion
Article #18801RE: Info sobre Sockets
From: Dakota
Date: Sun, 11 Jul 1999 00:00
Date: Sun, 11 Jul 1999 00:00
222 lines
8947 bytes
8947 bytes
gracias por la informacion, me va a ir de muerte pa aprender a programar en
LINUX :)
--
----
Internautas: http://www.internautas.org TARIFA PLANA YA!!!
-yo tambi�n 3000ya.com-
I Use Win98 (4.10.1998) & Red Hat 6.0 (2.2.10)
Dakota
javipa@TIMOmx4.redestb.es
Quita TIMO para responder! THX!
LINUX Registrered USER 93707 :)
<rdiazmar@localhost.localdomain> escribi� en el mensaje de noticias
slrn7occ81.16u.rdiazmar@localhost.localdomain...
> On Sat, 3 Jul 1999 18:09:20 +0200, Tony <cheng@jet.es> wrote:
>
> Esto lo escrib� yo para GNU-C no es que sea muy bueno pero es un
comienzo..
> .........................................................................
> Bueno para los que no saben hacerlo paso a dar una breve explicaci�n
> (basica)
>
> A ver si nos animamos y participamos mas...
>
> ------------Como hacer un cliente por Rober Diaz :-) -----------------
>
> Buneo los tutorials y ejemplos a veces se lian o porque no van al grano o
> porque van demasiado al grano.. esto es lo basico que hay que saber para
> que un cliente funcione..
>
> Primero hemos de saber como se manejan los datos... lo mas importante es
> la estructura sockaddr, que para el caso de conexiones a internet se llama
> sockaddr_in (hay un tipo sockaddr general por las que no nos preocupamos
> ahora).
>
> _Todas_ las fuciones a las que deberemos de pasar o que nos pasaran
> informacion sobre numero de puerto, direccion ip o familia de protocolos
> usan esta estructura por eso es tan importante.. o sea que sin ella no
> vamos a ningun lado..
>
> Esta estructura tiene el siguiente aspecto: (segun los ultimos tipos
> primitivos propuestos)
>
> struct sockaddr_in {
>
> unit8_t sin_len;
>
> /* Longitud de la estructura: una sockaddr_in tiene _siempre_ 16 bytes
> este campo se a�ade para guardar compatibilidad con todos los demas tipos
> de estructura sockaddr_ */
>
> sa_family_t sin_family;
> /* Familia de protocolos: esto en nuestro caso _siempre_ es AF_INET
> definido en los encabezados */
>
> in_port_t sin_port;
>
> /* Puerto: variable de 16 bit, compatible con IPv4-6 numero de puerto
> ordenado segun el orden de red */
>
> struct in_addr sin_addr;
>
>
> /* Direccion IP propiamente dicha: 32 bit IPv4, ordenados segun el orden
> de red */
>
> char sin_zero[8];
>
> /* Por compatibilidad con otros sockaddr_ de longitud variable */
>
> };
> O sea que las estructuras sockaddr_in _siempre_ son de 16 bytes, el orden
> de los bits en los campos que guardan la direcci�n IP y el numero de
> puerto estan en el orden de la red.
>
> Ahora si alguno se pregunta que es eso del orden de la red? pues facil..
> en la red la representacion siempre es Big Endian, o sea el bit mas
> significativo al comienzo de la direcci�n de memoria.. mientras que en
> linux es Little Endian, o sea el bit menos significativo al comienzo de la
> direcci�n de memoria.
>
> Esto plantea un problema.. hay que pasar los datos de little endian a big
> endian.. esto es lo que hacen la familia de funciones htons().. (Host TO
> Network Short en este caso).. es decir estas funciones solo ayudan en el
> cambio de los datos a representacion de red.
>
> Es _siempre_ necesario usarlas aunque estuviesemos en un UNIX big endian,
> dado que si no nuestro cliente no seria portable a otros con
> representacion little endian, en caso de otros UNIX big endian son macros
> nulas.
> La estructura in_addr simplemente almacena la direcci�n IP propiamente
> dicha:
>
> struct in_addr{
>
> in_addr_t s_addr;
>
> /* inicialmente se trat� de la union de un long mas una estructura
> constituida por 4 char (quedaban definidos cada uno de los numeros
> empleados en la notacion xxx.xxx.xxx.xxx) ahora se ha definido un tipo
> primitivo para su implementaci�n. */
>
> };
>
> De los miembros de la estructura sockaddr_in los importantes y los que
> debemos rellenar son: .in_addr, .sin_family y .sin_port
>
> struct sockaddr_in serv; (pseudocodigo)
>
> /* lo primero que debemos hacer es rellenar la estructura con ceros, eso
> es importante hacerlo siempre dado que el kernel puede comprobar otros
> campos adem�s de los que nosotros rellenamos para ello se puede usar o
> bzero() o memset(), se recomienda memset() */
>
> memset((struct sockaddr *) &serv, 0, sizeof(serv));
>
> /* se procede a rellenar la estructura */
>
> serv.sin_family = AF_INET;
> serv.sin_port;
> serv.sin_addr;
>
> para rellenar serv.sin_port empleamos HostTONetworkShort htons(),
> cambiando asi su representacion a big endian,
>
> unsigned long int puerto = 119;
> serv.sin_port = htons(puerto);
>
> para rellenar serv.sin_addr podemos usar inet_aton (inet_AscciTONetwork).
>
> char *ip;
> ip = "123.124.145.223"; /* direcci�n IP necesaria */
> struct in_addr server;
> inet_aton(ip, &server);
>
> /* inet_aton() nos devolvera cero si el formato de la direccion ip es
> incorrecto de otro modo nos devolver� un numero mayor que cero. Menor que
> cero si se produce cualquier otro error */
>
> ser.sin_addr = server;
>
> Ahora ya tenemos rellena la estructura con los datos necesarios podemos
> pasar a establecer la conexi�n.
>
> Un cliente es siempre muy sencillo solo usa las funciones socket() y
> connect().
>
> Hay que tener en cuenta que una conexi�n IP queda univocamente determinada
> por dos puertos y dos direcciones ip (correspondientes a los dos estremos
> de la comunicaci�n).. �como se especifica el primer extremo?
> La respuesta es que para un cliente esto frecuentemente no es necesario,
> dado que el kernel se ocupa de reservar un puerto disponible y toma la
> direcci�n ip del interfac de salida, sin embargo podr�amos especificarlo
> usando bind(), en este caso no vamos a hacerlo.
>
> /* creamos un asa de comunicaci�n */
>
> int sockfd;
> sockfd = socket (AF_INET, SOCK_STREAM, 0);
>
> /* vemos que no hemos especificado nada que no sea general, solamente la
> familia de protocolos el tipo de socket y que se use el protocolo por
> defecto, no se necesita nada caracteristico ni del cliente ni del
> servidor. Un socket es como tener un telefono, nada mas, para usarlo no es
> necesario conocer su numero. */
>
> Ahora conectamos al servidor. Decimos a que servidor usando la estructura
> sockaddr antes preparada:
>
> connect(sockfd, (struct sockaddr *) &serv, sizeof(serv));
> /* ambas funciones devuelven -1 caso de fallar y ponen errno al valor
> adecuado no olvideis verificar y en caso de error usar perror() */
>
> Cuando connect() retorna exitosamente, tras esperar una cantidad de tiempo
> de hasta un minuto si es necesario nuestro sockfd queda listo para ser
> usado en la comunicaci�n.
>
> A partir de entonces simplemente se usa write() o read(), o funiones de
> I/O analogas para establecer la comunicaci�n.
>
> Este es el codigo que siempre se emplea en los clientes en el dominio
> internet para una comunicaci�n TCP/IP, cierto que podriamos implementarlo
> de otro modo (incluidos raw sockets puestos a ser oscuros y exotericos)
> pero eso ya se ver� mas adelante.
>
> Si hubiesemos usado bind() para nuestro socket antes de efectuar el
> connect() incluso podr�amos haber hecho un spoofing (pero todav�a no hemos
> llegado al punto de saber lo suficiente para caer en esa tentaci�n).
>
> Bueno pues que se me hace tarde ma�ana sigo con un ejemplo y continuo con
> un servidor b�sico. Tambi�n contar� proximamente como se cierra bien un
> socket.
>
> --------------------------------------------------------------------------
--
>
>
>
> >Hay un manual sobre programaci�n de sockets en el programa "info", pero
est�
> >en ingl�s (como casi todo). Creo que estaba dentro del manual de las
> >librer�as de C.
> >
> >Jorge L�pez escribi� en mensaje <377d061d@dial-in.encomix.es>...
> >>Hola a todos.
> >>
> >>Estoy iniciandome a la programaci�n de sockets y agradecer�a si alguien
> >>conoce alguna dir�cci�n interesante sobre la programaci�n de estos.
> >>
> >>Gracias.
> >>
> >>
> >
> >
>
>
> --
>
> Saludos
>
> Roberto D�az <rdiazmar@nova.es>
> http://www.linuxfocus.org/developer/Roberto
Technical Details
Message-ID:
<7mb0gc$gsh@wendy.mad.servicom.es>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailReferences:
<377d061d@dial-in.encomix.es> <7lovdd$2r2$1@diana.bcn.ttd.net> <slrn7occ81.16u.rdiazmar@localhost.localdomain>Show Full Headers
Complete Article Headers
X-Google-Language: SPANISH,ASCII X-Google-Thread: f86c8,eebfd124c9fbd7f5 X-Google-Attributes: gidf86c8,public From: "Dakota" <javipa@TIMOmx4.redestb.es> Subject: RE: Info sobre Sockets Date: 1999/07/11 Message-ID: <7mb0gc$gsh@wendy.mad.servicom.es> X-Deja-AN: 499871709 References: <377d061d@dial-in.encomix.es> <7lovdd$2r2$1@diana.bcn.ttd.net> <slrn7occ81.16u.rdiazmar@localhost.localdomain> X-Priority: 3 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2314.1300 Organization: QUIERO TARIFA PLANAAAAA X-MSMail-Priority: Normal Reply-To: "Dakota" <news@dakota.dhis.org> Newsgroups: es.comp.os.linux.programacion