Autor
|
Tema: Dudas en la Programacion de Sockets en C !! (Leído 870 veces)
|
Diabliyo
Desconectado
Mensajes: 1.334
M.S.I Angel Cantu
|
Hola: Tengo varias dudas sobre este tema, ya que aun estoy estudiando el tuto de Beej, bueno.... Ir poniendo mis dudas aqui.... No entiendo muy bien el uso de las funciones: htonl() ---> de Host a Red Long htons() ---> de Host a Red Short ntohl() ---> de Red a Host Long ntohs() ---> de Red a Host Short Como puedo saber cuando usar un tipo de funcion ?? osea en este ejemplo: #define MYPORT 2020 my_addr.sin_addr.s_addr= htonl( MYPORT ); Ahi un rango para saber cuando se va a usar SHORT o LONG ??? byeeeeeeeeee
|
|
|
|
|
En línea
|
|
|
|
Diabliyo
Desconectado
Mensajes: 1.334
M.S.I Angel Cantu
|
Hola: Bueno... creo que no es tan importante eso...  ... Aqui tengo otro problemita y es en codigo... espero a este si pueda obtener una respuesta  ..... El proble es que NO llega el MENSAJE ni al cliente ni al servidor  ... lo estoy ejecutando en mi misma PC... Es mi primer programa, compila bien y corre, pero no llega el mensaje. Ejecuto primero ./servidor, despues en otra terminal ./cliente, y pues el cliente espera el MENSAJE, aca en el Servidor envio el mensaje, pero despues en las dos terminales sale: Violacion de Segmento.. Gracias por su Atencion byeeee
|
|
|
|
|
En línea
|
|
|
|
Diabliyo
Desconectado
Mensajes: 1.334
M.S.I Angel Cantu
|
Codigo de servidor.c: #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h>
#define PORT 15005 #define BACKLOG 5
/*PROTOTIPOS*/
int socket_server( void ); int socket_cliente( int sockds ); void enviar_cliente( int sockds_n, char *cad ); char reciv_cliente( int sockds_n );
char reciv_cliente( int sockds_n ) { char *buf; int size_buf; size_buf= strlen( buf ); recv( sockds_n, buf, size_buf, 0 ); return *buf; }
void enviar_cliente( int sockds_n, char *cad ) { int size_m; size_m= strlen( cad ); send( sockds_n, cad, size_m, 0 ); return; }
int socket_cliente( int sockds ) { int sockds_n, size_c; struct sockaddr cliente; size_c= sizeof( struct sockaddr_in ); if( (sockds_n= accept( sockds, &cliente, &size_c )) == -1 ) { printf( "\n\nProblemas para aceptar Cliente." ); close( sockds ); getchar(); return -1; } return sockds_n; }
int socket_server( void ) { int sockds; struct sockaddr_in server; if( (sockds= socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) return -1; server.sin_family= AF_INET; server.sin_port= htons( PORT ); server.sin_addr.s_addr= INADDR_ANY; memset( &(server.sin_zero), '\0', 8 ); if( (bind( sockds, (struct sockaddr *)&server, sizeof( struct sockaddr ) )) == -1 ) { printf( "\n\nProblemas para asociar el socket con el Puerto." ); close( sockds ); getchar(); return -1; } listen( sockds, BACKLOG ); return sockds; }
int main() { int sockds, sockds_n; char cad[20];
system( "clear" ); if( (sockds= socket_server() ) == -1 ) { printf( "\nProblemas para conectar el socket." ); getchar(); exit(-1); } if( (sockds_n= socket_cliente( sockds ) ) == -1 ) { printf( "\n\nProblemas con Cliente." ); getchar(); exit(-1); } system( "clear" ); printf( "Mensaje a Enviar al Cliente: " ); scanf( "%s", &cad ); enviar_cliente( sockds_n, cad ); printf( "\n\nHas Recivido: %s", reciv_cliente( sockds_n ) ); printf( "\n\nFin.... Pulsa para salir.." ); close( sockds ); getchar(); return 0; }
|
|
|
|
|
En línea
|
|
|
|
Diabliyo
Desconectado
Mensajes: 1.334
M.S.I Angel Cantu
|
Codigo de cliente.c: #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h>
#define PORT 15005 #define BACKLOG 5
/*PROTOTIPOS*/
int socket_server( void ); void cliente_enviar( int sockds, char *cad ); char cliente_reciv( int sockds );
char cliente_reciv( int sockds ) { char *buf; int size_buf; size_buf= strlen( buf ); recv( sockds, buf, size_buf, 0 ); return *buf; }
void cliente_enviar( int sockds, char *cad ) { int size_m; size_m= strlen( cad ); send( sockds, cad, size_m, 0 ); return; }
int socket_server( void ) { int sockds; struct sockaddr_in server; if( (sockds= socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) return -1; server.sin_family= AF_INET; server.sin_port= htons( PORT ); server.sin_addr.s_addr= INADDR_ANY; memset( &(server.sin_zero), '\0', 8 ); if( connect( sockds, (struct sockaddr *)&server, sizeof( struct sockaddr ) ) == -1 ) { printf( "\n\nProblemas para Conectar con el Servidor." ); close( sockds ); getchar(); return -1; } return sockds; }
int main() { int sockds; char cad[20];
system( "clear" ); if( (sockds= socket_server() ) == -1 ) { printf( "\nProblemas para conectar el socket." ); getchar(); exit(-1); } system( "clear" ); printf( "\n\nHas Recivido: %s", cliente_reciv( sockds ) ); printf( "Mensaje a Enviar al Servidor: " ); scanf( "%s", &cad ); cliente_enviar( sockds, cad ); printf( "\n\nFin.... Pulsa para salir.." ); close( sockds ); getchar(); return 0; }
|
|
|
|
|
En línea
|
|
|
|
Diabliyo
Desconectado
Mensajes: 1.334
M.S.I Angel Cantu
|
Hola: Gracias _kuka_ por contestar, bueno, gracias a la modificacion que le hicistes ya entendi bien como enviar y recivir, pero el problema es que, al momento de RECIVIR, se reciven caracteres raros... osea.... Ejemplo: En el Servidor escribir: hola
El cliente Recivio: hola $%^^& ( el mensaje y 5 caracteres raros ).
El Cliente Escribio: vaca
El Servidor Recivio: vaca &^%*# ( el mensaje y 5 caracteres raros ). Por logica algo tengo que solucionar en la funcion: reciv_cliente() y cliente_reciv(). Que puedo hacer ???? ( de todos modos le estare intentando ) byeeee
|
|
|
|
|
En línea
|
|
|
|
_kuka_
Desconectado
Mensajes: 10
|
lee caracteres raros porque le falta el caracter '\0' para que se detenga ya que estas utilizando printf( )
en tu funcion que recibe datos podrias ponerle esto
numbytes=recv(sockds, buf, size_buf, 0) buf[numbytes] = '\0';
|
|
|
|
|
En línea
|
|
|
|
Diabliyo
Desconectado
Mensajes: 1.334
M.S.I Angel Cantu
|
Hola: Gracias de nuevo _kuka_. He puesto el codigo que dices, ya que al momento de que la funcion recv recive el mensaje, regresa el num de caracteres recividos en bytes, por eso lo alojamo en la varibale bytes_n y despues el array de cadena tipo puntero que es buf le agregamos el salto de linea '\0' al final.... int size_buf, bytes_n;
bytes_n= recv( sockds, buf, size_buf, 0 ); buf[bytes_n]='\0'; Y ademas quite el pedazo de codigo que va en el int main(), ya que este codigo contaba la longitud de la cadena JUNTO con los caracteres raros  , el codigo eliminado fue: int i;
i= strlen(buf)+1; buf[i]='\0'; Muy bien quedo comprendido perfectamente ... gracias de nuevo compa _kuka_. Saludos desde Reynosa Tamaulipas, Mexico compa !!! byeeeeeeee
|
|
|
|
« Última modificación: 27 Febrero 2005, 05:49 por Diabliyo »
|
En línea
|
|
|
|
Griph
Desconectado
Mensajes: 253
|
El tema de la programación de es muy interesante, lástima que no hayan dejado las explicaciones que te habrá dejado el compañero _kuka_, no lo digo por mí sino por la gente que anda buscando información sobre programación de sockets en lenguaje C bajo GNU/Linux. No entiendo muy bien el uso de las funciones:
htonl() ---> de Host a Red Long htons() ---> de Host a Red Short ntohl() ---> de Red a Host Long ntohs() ---> de Red a Host Short
Estas funciones convierten valores en los cuales sus bytes que estan en orden de host a valores cuyos bytes se encuentran en orden red. El proceso se puede dar de las dos formas, bytes en orden host a bytes orden de redes; y byte en orden de red a bytes en orden de host. Específicamente cada función hace lo siguiente: * Funciones que trabajan con los bytes en orden de host: La función htonl() convierte el [entero largo hostlong] desde el orden de bytes del host al de la red. La función htons() convierte el [entero corto hostshort] desde el orden de bytes del host al de la red. * Funciones que trabajan con los bytes en orden de red: La función ntohl() convierte el [entero largo netlong] desde el orden de bytes de la red al del host. La función ntohs() convierte el [entero corto netshort] desde el orden de bytes de la red al del host. * Según los prototipos de estas funciones: Cuando un entero es largo quiere decir que es del siguiente tipo: long int Cuando un entero es corto quiere decir que es del siguiente tipo: short int Para usar estas funciones debemos hacer que la directiva "#include" del preprocesador del compilador gcc agregue el siguiente fichero header: netinet/in.h La sinópsis/sintaxis completa es la siguiente: #include <netinet/in.h>
unsigned long int htonl(unsigned long int hostlong); unsigned short int htons (unsigned short int hostshort); unsigned long int ntohl(unsigned long int netlong); unsigned short int ntohs(unsigned short int netshort);
Saludos, Griph
|
|
|
|
|
En línea
|
"...la Base está en Aprender a Programar..."
|
|
|
Diabliyo
Desconectado
Mensajes: 1.334
M.S.I Angel Cantu
|
Hola: Gracias por la explicacion Griph. Ahora como duda vaga ( ya que se me esconde el dato detras de otras neuronas  ). El 2020 es un entero LARGO qu usaria htonl()Y 11111100100 es Entero largo de tipo RED que usa la funcion ntohl()Entero Largo es de 32 bits Entero Corto es de 16 bits Ultima Aclaracion: El uso de inet_aton() se enfoca mas en lo que es el IP no ???... Para convertir el IP que esta escrito en ASCII y pasarlo a codigo red ( cadena de bits ). Ejm: ASCII 100.100.100.50 Red 01100100.01100100.01100100.00110111 La IP se es de 32 bits !. Y por logica inet_ntoa() se usaria posteriormente para obtener la IP de algun cliente en ASCII !! Cierto ???? byeeeeeeeeee
|
|
|
|
« Última modificación: 27 Febrero 2005, 13:17 por Diabliyo »
|
En línea
|
|
|
|
|
|