Autor
|
Tema: Servidor de sockets en c (Leído 3,806 veces)
|
xGisKaRDx
Desconectado
Mensajes: 6
|
Hola amigos estoy intentando de hacer un servidor de sockets en c bajo linux y bueno sinceramente no tengo mucha idea de c y me cuesta bastante entenderlo, ya no tengo capacidad para aprender un lenguaje de tan bajo nivel. Bueno a lo que iba solo quiero aprender lo que implica de un servidor de sockets para poder hacer un servidor para un juego, bueno en realidad serán 2 servidores un para el juego y el otro para servir un crossdomain.xml De momento he empezado a hacer pruebas con el servidor encargado de servir el xml la lógica consiste en lo siguiente, el cliente se conecta al servidor de xml al puerto 843 y le manda una cadena, el servidor comprueba dicha cadena y si la cadena coincide le contesta con un xml, una vez el cliente tiene el xml se desconecta automáticamente de ese servidor y se conecta al servidor del juego, el problema reside en que no me devuelve el xml. Para probar el servidor lo que hago de momento es conectarme a través de telnet y una vez conectado le envió la cadena "<policy-file-request/>" y el servidor debería enviarme el xml, pero no me lo devuelve en la consola de putty puedo ver mediante el comando put() como la cadena que yo le envió al servidor le llega de la siguiente manera. < policy-file-request/> El primer carácter lo muestra en una línea y el resto de la cadena en la siguiente, no sé si esto puede llegar a afectar en algo. A mí en cambio en la consola de telnet el servidor me devuelve la cadena que yo le envié de manera correcta <policy-file-request/> pero me tendría que devolver también el xml En definitiva el siguiente if no se está cumpliendo if(strcmp(buffer, "<policy-file-request/>")==0){ El código de ejemplo que estoy utilizando es este, agradezco cualquier corrección o ayuda. #include<stdio.h> #include<string.h> //strlen #include<sys/socket.h> #include<arpa/inet.h> //inet_addr #include<unistd.h> //write int main(int argc , char *argv[]) { int socket_desc , new_socket , c; struct sockaddr_in server , client; char *message , buffer[2000]; int read_size; //Create socket socket_desc = socket(AF_INET , SOCK_STREAM , 0); if (socket_desc == -1) { printf("Could not create socket"); } //Prepare the sockaddr_in structure server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; server.sin_port = htons( 843 ); //Bind if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) { return 1; } //Listen listen(socket_desc , 5); //Accept and incoming connection puts("Waiting for incoming connections..."); c = sizeof(struct sockaddr_in); while( (new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c)) ){ puts("Conexion establecida al servicio de crossdomain policy"); //Miramos que nos dice el cliente //memset(buffer, '\0', sizeof( buffer )); // read_size = recv(new_socket , buffer , 20 , 0); //Receive a message from client while( (read_size = recv(new_socket , buffer , 2000 , 0)) > 0 ){ //Send the message back to client if(strcmp(buffer , "<policy-file-request/>")==0){//Si concuerda con la cadena "<policy-file-request/>" enviamos el cossdoamain al cliente message = "<?xml version=\"1.0\"?><!DOCTYPE cross-domainpolicy- SYSTEM \"http://www.adobe.com/xml/dtds/crossdomain.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>"; write (new_socket , message , strlen(message )); } write (new_socket , buffer , strlen(buffer )); } if(read_size == 0){ puts("Client disconnected"); }else if(read_size == -1){ } }//End While if (new_socket<0){ return 1; } return 0; }
|
|
|
En línea
|
|
|
|
MeCraniDOS
Desconectado
Mensajes: 337
Sr. Glass
|
Esto está malmessage = "<?xml version=\"1.0\"?><!DOCTYPE cross-domainpolicy- SYSTEM \"http://www.adobe.com/xml/dtds/crossdomain.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>";
Declaras un puntero a message pero no especificas tamaño, y por lo que he visto, message siempre tiene ese contenido, asi que prueba esto:
En la declaración de las variables:int socket_desc , new_socket , c; struct sockaddr_in server , client; char buffer[2000], message[] = "<?xml version=\"1.0\"?><!DOCTYPE cross-domainpolicy- SYSTEM \"http://www.adobe.com/xml/dtds/crossdomain.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>"; int read_size;
Y en el if, tienes esto:if(strcmp(buffer , "<policy-file-request/>")==0) { //Si concuerda con la cadena "<policy-file-request/>" enviamos el cossdoamain al cliente message = "<?xml version=\"1.0\"?><!DOCTYPE cross-domainpolicy- SYSTEM \"http://www.adobe.com/xml/dtds/crossdomain.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>"; write (new_socket , message , strlen(message ));}
Cambialo por estoif(strcmp(buffer , "<policy-file-request/>")==0) { //Si concuerda con la cadena "<policy-file-request/>" enviamos el cossdoamain al cliente write (new_socket , message , strlen(message ));}
Si te sigue fallando lo miraré a ver cual puede ser el error
Saludos
|
|
|
En línea
|
"La física es el sistema operativo del Universo" -- Steven R Garman
|
|
|
xGisKaRDx
Desconectado
Mensajes: 6
|
Hola MeCraniDOS, gracias por tu respuesta al final me ha funcionado con tus correcciones, gracias Sinceramente vengo de lenguajes de alto nivel como js,php,as3,vb y c# y me cuesta mucho entender cosas como los punteros o por ejemplo me choca que no pueda comparar 2 cadenas tal cual en fin tiene mucha telita el c. supongo que al disponer de acceso a más bajo nivel se tiene más control pero para los cabeza duras como yo se nos hace un mundo. Ya que estoy aprovecho para preguntar algunas cosillas, yo ahora mismo estoy programando en c con el notepad++ desde windows, cada vez que realizo algún cambio en el programa y quiero probarlo tengo que subirlo al ftp del vps(centos) después desde el putty lo compilo, mato el proceso del programa anterior desde el power panel y vuelvo a ejecutar el actualizado desde el putty para poder después probar el cambio realizado en el programa. La pregunta es, hay alguna manera desde windows que yo pueda debuguear el servidor de sockets sin tener que hacer todos esos pasos cada vez que hago un cambio? y para terminar, antes de seguir con el servidor de sockets en c me recomiendan algún otro lenguaje de más alto nivel para hacer el servidor de sockets pero que se ejecute desde linux como lo hace el c? Bueno pues eso es todo, gracias y si sigo con el c seguramente iré viniendo más a menudo a visitarles jeje Aquí dejo el código final de la duda anterior por si a alguien le sirve #include<stdio.h> #include<string.h> //strlen #include<sys/socket.h> #include<arpa/inet.h> //inet_addr #include<unistd.h> //write int main(int argc , char *argv[]){ int SOCKET_MASTER; int SOCKET_CLIENT; int sockAddrClientLen; int read_size; struct sockaddr_in structServer; struct sockaddr_in structClient; char xml_message[] = "<?xml version=\"1.0\"?><!DOCTYPE cross-domainpolicy- SYSTEM \"http://www.adobe.com/xml/dtds/crossdomain.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>"; char error_message[] = "No se a enviado el xml porque no coincide el comando, la cadena recibida a sido:\n"; char buffer[2000]; /* * Creamos el SOCKET_MASTER */ if ((SOCKET_MASTER = socket(AF_INET , SOCK_STREAM , 0)) == -1){ printf("Could not create socket"); } /* * Cumplimentamos los valores de configuracion de la estructrua sockaddr_in */ structServer.sin_family = AF_INET; structServer.sin_addr.s_addr = INADDR_ANY; structServer.sin_port = htons( 843 ); /* * Enlazamos el socket master a la ip y el puerto especificado en la estructura del server */ if( bind(SOCKET_MASTER,(struct sockaddr *)&structServer , sizeof(structServer)) < 0){ puts("Fallo en el enlace/Bind"); return 1; }else{ puts("Enlace realizado"); } /* * Ponemos el socket a la escucha y con un maximo de 5 clientes en espera */ listen(SOCKET_MASTER , 5); puts("Esperando conexiones entrantes..."); /* * Ponemos el socket a la escucha y con un maximo de 5 clientes en espera */ sockAddrClientLen = sizeof(struct sockaddr_in); /* * Comprobamos mediante un bucle si se conecta algun cliente por el socket_master, si es asi aceptamos la conexion y creamos un nuevo socket para el cliente */ while( (SOCKET_CLIENT = accept(SOCKET_MASTER, (struct sockaddr *)&structClient, (socklen_t*)&sockAddrClientLen)) ){ puts("Conexion establecida al servicio de crossdomain policy"); //Inicializamos el buffer a 0 //Comprovamos si el cliente conectado nos envia algun dato while( (read_size = recv(SOCKET_CLIENT , buffer , 2000 , 0)) > 0 ){ //Mostramos en consola/putty el mensaje del cliente //Comparamos si el mensaje enviado por el cliente coinciden los 20 primeros digitos con la siguiente cadena -> <policy-file-request/> if(strcmp(buffer , "<policy-file-request/>")==0){ //Si coincide le enviamos al cliente el xml write (SOCKET_CLIENT , xml_message , strlen(xml_message )); }else{ //Si no coicide avisamos al cliente y le devolvemos tambien lo que nos envio el write (SOCKET_CLIENT , error_message , strlen(error_message )); write (SOCKET_CLIENT , buffer , strlen(buffer )); } //Reiniciamos a 0 el buffer }//End While read_size if(read_size == 0){ puts("Cliente desconectado"); fflush(stdout );//Forzamos a mostrase la cadena del buffer en consola }else if(read_size == -1){ } }//End While SOCKET_CLIENT if (SOCKET_CLIENT<0){ perror("Error al Aceptar el nuevo Cliente/Socket"); return 1; } return 0; }
MeCraniDOS cante victoria demasiado pronto, al ver que me devolvia el xml di por sentado que ya funcionava bien, pero el problema ahora es que mande lo que mande desde el telnet al servidor el servidor me devuelve el xml y solo me lo tiene que devolver si yo le mando la cadena <policy-file-request/> PD: ya esta solucionado xd en la linea 70 estaba enviando nuevamente la variable xml_message y tenia que poner la variable error_message, ya esta corregido en el codigo.
Bueno pues sigue fallando... la que estoy liando qie si va que si no va.. en fin. Ahora cuando envio una cadena desde telnet por ejemplo "hola" en la consola muestra primero la primera lentra en una linea y el restro de la frase en la otra por ejemplo: h ola Sin envio "elhacker" en consola me aparece e lhacker supomngo que por eso cuando envio "<policy-file-request/>" la sentencia if no se cumple y no me envia el xml porque en vez de llegar al buffer la cadena "<policy-file-request/>" llega primero el "<" y luego el resto "policy-file-request/>" es como si la linea del -> while( (read_size = recv(SOCKET_CLIENT , buffer , 2000 , 0)) > 0 ){ leiera el primer caracter del comando recibido y lo enviara y despues leiera el resto del comando Si envio el comando desde telnet precedido por un espacio o alguna letra entonces funciona por ejemplo: x<policy-file-request/> el servidor muestra en una linea la x y en la siguiente el resto x <policy-file-request/> Entonces como se cumple la sentencia me devuelve el xml Alguien sabe a que es debido ese comportamiento, porque el servidor corta la primera letra del resto de la cadena y lo muestra por separado?
Bueno espero que esta sea la ultima vez que digo que ya funciona bien y luego no.. En principio el problema venia por hacer las pruebas desde telnet, no me pregunteis porque, porque no tengo ni puñetera idea. La cuestion es que he creado un cliente en flash me conectado y funciona a las mil maravillas Saludos
|
|
« Última modificación: 11 Julio 2014, 20:16 pm por Eternal Idol »
|
En línea
|
|
|
|
vangodp
Desconectado
Mensajes: 455
|
no se nada de socktes pero lo de no pueda comparar 2 cadenas tal cual en fin tiene mucha telita el c se arregla guardando como C++ y entonces puedes utilizar todo el arsenal XD string palabra = "hola"; i( palabra == "hola"){ //correcto } y puedes seguir usando c igual sin problemas >_< C esta en C++
|
|
|
En línea
|
|
|
|
naderST
|
Esto está malmessage = "<?xml version=\"1.0\"?><!DOCTYPE cross-domainpolicy- SYSTEM \"http://www.adobe.com/xml/dtds/crossdomain.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>";
Declaras un puntero a message pero no especificas tamaño, y por lo que he visto, message siempre tiene ese contenido, asi que prueba esto: ...
En realidad, eso no está mal... la cadena "<?xml version=\"1.0\"?><!DOCTYPE cross-domainpolicy- SYSTEM \" http://www.adobe.com/xml/dtds/crossdomain.dtd\"><cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\" /></cross-domain-policy>" es un literal y el apuntador message apunta a este. Al declarar una cadena en C entre comillas dobles automáticamente se agrega el caracter nulo (\0) al final, por lo tanto se pueden utilizar las funciones de la librería string tales como strlen y strcmp . Exactamente no se cual es el problema que tienes, pero sin duda alguna esa declaración no es parte del problema. Por otra parte, dependiendo de lo que quieras hacer, puedes utlizar node.js o Python y te evitarás problemas con detalles de C
|
|
|
En línea
|
|
|
|
xGisKaRDx
Desconectado
Mensajes: 6
|
Hola gracias por los comentarios, en realidad me estoy planteando, montarlo en java en vez de en c que por lo visto tambien puedo hacerlo correr en linux, ya que veo que en java practicamente todas estas cosas de bajo nivel estan axtraidas. no quiero hacerme la vida imposible con el servidor de sockets porque luego me quedara toda la programacion por parte del cliente/juego que es donde quiero invertir el tiempo.
Osea me gustaria un lenguaje parecido a algo que ya conociera de alto nivel como js, php, as3 (ya monte un servidor de sockets en php y no me convencio, tambien lo monte en adobe air pero no puedo instarlo en el vps porque ya no tiene soporte para linux, aunque podria instalarlo en uno windows pero el precio se dispara)
Asi que, que me recomiendan para crear un proceso de sockets para linux? java o c++?
|
|
|
En línea
|
|
|
|
naderST
|
Hola gracias por los comentarios, en realidad me estoy planteando, montarlo en java en vez de en c que por lo visto tambien puedo hacerlo correr en linux, ya que veo que en java practicamente todas estas cosas de bajo nivel estan axtraidas. no quiero hacerme la vida imposible con el servidor de sockets porque luego me quedara toda la programacion por parte del cliente/juego que es donde quiero invertir el tiempo.
Osea me gustaria un lenguaje parecido a algo que ya conociera de alto nivel como js, php, as3 (ya monte un servidor de sockets en php y no me convencio, tambien lo monte en adobe air pero no puedo instarlo en el vps porque ya no tiene soporte para linux, aunque podria instalarlo en uno windows pero el precio se dispara)
Asi que, que me recomiendan para crear un proceso de sockets para linux? java o c++?
Lo más parecido a lo que mencionas es node.js y si quieres más abstracción y tus opciones son Java y C++ te recomiendo que te vayas por Java. Sin embargo, node.js se programa utilizando javascript prácticamente.
|
|
|
En línea
|
|
|
|
xGisKaRDx
Desconectado
Mensajes: 6
|
Gracias creo que optare por remirarme tanto c++ como java y luego decidiré, en cuanto a node.js la verdad es que me atrae el tema del control de los hilos mediante eventos pero sinceramente no me gusta javascript, es feo y malo de narices, en fin no me gusta para la web así que menos para el servidor, lástima que tengamos que tragarlo por fuerza.
además no veo un sistema de inicio claro en la instalación de node.js como por ejemplo c que tan solo tuve que poner en mi vps centos una línea para instalar el compilador gcc y a funcionar los programas con ./programa.out, no tuve que tocar nada más.
Espero que nadie se ofenda
Gracias de nuevo y un salúdate.
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Problema con sockets Cliente - Servidor ( IP )
Programación Visual Basic
|
EstoyBaneado
|
8
|
3,752
|
22 Agosto 2005, 02:06 am
por soplo
|
|
|
VB.NET sockets cliente-servidor
.NET (C#, VB.NET, ASP)
|
Blizknight
|
2
|
13,661
|
11 Marzo 2008, 04:53 am
por elmaro
|
|
|
AYUDA CON SOCKETS (CLIENTE/SERVIDOR)
Programación C/C++
|
ApOkAlizE
|
4
|
4,672
|
29 Febrero 2012, 22:56 pm
por avmiitxe
|
|
|
Cliente / Servidor con sockets en Visual c++
Programación General
|
rabbar
|
0
|
2,043
|
27 Noviembre 2013, 18:15 pm
por rabbar
|
|
|
SOCKETS SERVIDOR AYUDA PORFAVOR!!
Java
|
Pitagoras
|
2
|
2,815
|
7 Mayo 2022, 19:15 pm
por K-YreX
|
|