PDA

Ver la versión completa : Porblemas con socket C



chewarrior
10-10-2010, 22:50
Bueno el problema es que el servidor 1 me tiene que enviar datos a mi, para que yo pueda enviarle datos a el





#include <stdio.h>
#include <winsock.h>
#include <string.h>
#include <conio.h>
#define puerto 190
main(){
//variables
WSADATA wsa;

int sock,conectado;
char buffer[1024]="",bienvenido[22]="welcome to my server";
struct sockaddr_in server;
WSAStartup(MAKEWORD(2,0),&wsa);

if((sock=socket(AF_INET,SOCK_STREAM,0))<0){; // creamos el socket
printf("Error creando el socket, saliendo…");
getch();
exit(0);
}

server.sin_family= AF_INET; // familia socket
server.sin_addr.s_addr=INADDR_ANY;
server.sin_port=htons(puerto); //Puerto

if(bind(sock,(struct sockaddr *)&server,sizeof(server))<0 ){//bindeamos…
printf("error asociando socket al puerto…");
getch();
exit(0);
}

printf("En escucha");
listen(sock,1); // nos kedamos a la eskuxa con una cola de maximo 5 clientes


if((conectado=accept(sock,0,0))<0){
printf("error aceptando connexion");
exit(0);
}

if(send(conectado,bienvenido,sizeof(bienvenido),0)<0){ //
printf("error enviando msg de bienvenida");
exit(0);
}

if(recv(conectado,buffer,sizeof(buffer),0)==-1){
printf("error reciviendo");

exit(0);
}
printf("mensaje del cliente: %s\n",buffer);
getch();
memset(buffer,0,sizeof(buffer)); // esta funcion vacia
getch();
closesocket(conectado); //cerramos el socket.



return 0;
}





Si quito la funcion enviar adios, el cliente ya no conecta



if(send(conectado,bienvenido,sizeof(bienvenido),0)<0){ //
printf("error enviando msg de bienvenida");
exit(0);
}


La misma situacion si quito el recv de el cliente


Aqui el codigo cliente;



#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>
#define ip "127.0.0.1" //ip del servidor al ke konectar
#define puerto 190 //puerto del server

int main()
{
WSADATA wsa;

int sock;//descriptor del socket.
struct sockaddr_in direccion; //datos del servidor al ke konectaremos
char buffer[1024]; //bufer donde guardaremos lo ke nos envie el Server.
char cadena[1024]; // la info ke enviaremos al Server.

WSAStartup(MAKEWORD(2,0),&wsa);

if((sock=socket(AF_INET,SOCK_STREAM, 0))<0 ){ // obtenemos el descriptor del socket

printf("problema al crear el stock");
getch();
exit(0);
}
else{
printf("socket creado con exito");


direccion.sin_family=AF_INET;// protocolo af inet, visto antes.
direccion.sin_port=htons(puerto);//htons convierte el puerto al formato de red.
direccion.sin_addr.s_addr=inet_addr(ip);

//conectamos al servidor
if(connect(sock,(struct sockaddr*)&direccion,sizeof(direccion))<0){
printf("error conectando…");
getch();
exit(0);
}

if(recv(sock,buffer,sizeof(buffer),0)==-1){

printf("Error recibiendo msg, saliendo…");
exit(0);
}
printf("conectado al servidor\n");
printf("Mensagje a enviar: ");
while(strcmp(cadena,"salir")){

gets(cadena);

if(send(sock,cadena,strlen(cadena),0)==-1){
printf("error enviando msg, cerrando…");
getch();
exit(0);

}
}
printf("\nMensage enviado. Esperando respuesta…");
printf("Mensaje recibido: %s",buffer);
getch();

}
return 0;
}






si quito recv ya me puedo ir olvidando de enviar nada




if(recv(sock,buffer,sizeof(buffer),0)==-1){

printf("Error recibiendo msg, saliendo…");
exit(0);
}



Pues ya ven mas claro creeo que no se puede ser, haber si alguien me puede ayudar ya que yo no doy con la solucion, hace poco emepeze con esto de los socket y con la basica y muy mala explicacion que dispongo no puedo solucionar el problema.

El code origanal es de un tal Berty el cual tenia un monton de fallos que yo e corregido, pero pude ser que berty no tubiera mucha idea de socket, la misma que yo mas o menos, y en la funcion conect o alguna otra hubiera un fallo y por eso el cliente deve recivir datos del servidor para posteriormente enviar del cliente al servidor.

hystd
11-10-2010, 03:33
Si te he entendido bien, quieres que para que se envie un dato del cliente al servidor, primero el servidor ha de mandar un mensaje ¿no? y cuando el cliente reciba ese mensaje, podrá responder al servidor ¿cierto?. A ver qué se puede hacer...

Las funciones accept() y recv() son bloqueantes, de forma que bloquean o "pausan" la ejecución del proceso hasta que se establezca una conexión o se reciba un dato respectivamente.

Haciendo una traza "a ojo", se hace lo siguiente (no lo he probado pues no tengo compilador a mano ni máquina linux (estoy en un pc que no es mio)...

En el servidor:
1º Creas el socket con socket() --> Ok, aunque para conexiones TCP, debes poner 6 en vez de 0 (0 corresponde a IP), ¿quizá aquí pueda deberse el error?, puede ser... IP no garantiza la correcta transferencia de datos por tratarse de un protocolo de red. TCP si lo hace pues está en una capa superior (transporte). No obstante creo que tu problema es otro.
2º Asignas dirección y puerto con bind() --> Ok.
3º Permaneces a la escucha con listen() ---> Ok.
4º Bloqueas la ejecución con accept(), a la espera de que se realice una conexión --> Ok.

En el cliente:
1º Creas el socket --> Ok. con la misma advertencia que en el servidor.
2º Realizas la conexión con connect() --> Ok. El servidor que estaba bloqueado con accept() ahora se desbloquea y continua su ejecución.
3º El cliente llama a recv() y se bloquea a la espera de que el servidor responda.


En el servidor:
5º Llama a send() --> Ok, envia datos al cliente y éste se desbloquea.
6º Llama a recv() --> Ok, ahora el servidor se bloquea esperando que el cliente responda.


En el cliente:
4º Se entra en un bucle, en el que mientras la cadena que teclea el usuario no sea "salir":
4.1º. Envia esa cadena al servidor con send() --> Ok, el servidor ahora se desbloquea.
4.2º ATENCIÓN: ahora el cliente no está bloqueado y sigue su ejecución
4.3º Imprime mensajes... vuelve a entrar en el bucle y vuelve a 4.1.


En el servidor:
7º Se recibe el mensaje, se imprime... y se cierra el descriptor de fichero del socket (ya no se aceptan más peticiones).


En el cliente:
4.1º Se envia cadena al servidor con send() --> NO OK. pues el socket ya se ha cerrado... send() devuelve -1, imprime mensaje error y finaliza.


Revisa lo que está marcado en rojo y creo que solucionarás lo que creo haber entendido de tu problema.

Un saludo.

chewarrior
11-10-2010, 20:40
Esto esta solucionado, gracias por la respuesta.