problemas con sockets..
Buenas, estoy trasteando un poco con sockets entre maquinas y me he topado con un problema.. ¬¬ pa variar.. xDDD no se como solucionar el error..
Se trata de un proceso cliente y otro servidor corriendo en maquinas distintas..
Proceso cliente:
#include <stdio.h>
#include <netdb.h> /* gethostbyname() necesita esta cabecera */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
int main(){
struct sockaddr_in server_addr;
int sd;
char *msg;
sd = socket(AF_INET, SOCK_STREAM, 0);
/*obtenemos la direccion del servidor...*/
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(6969);
server_addr.sin_addr.s_addr = inet_addr("192.168.0.4");
// memset(&(server_addr.sin_zero), 0, 8);
/*establecemos conexión...*/
if(connect(sd,(struct sockaddr *) &server_addr, sizeof(struct sockaddr)) < 0){
error("\nError en la llamada connect");
}else printf("\nConexión establecida...");
sleep(1);
printf("\n\nIntroduce un mensaje ===> ");
scanf("%s",&msg);
if(write(sd,(char *)&msg, 25)==-1)perror("\nError enviando mensaje...");
else printf("\nMensaje enviado/recibido... %s",&msg);
strcpy((char *)&msg,"");
if(read(sd,(char *)&msg, 25)==-1) perror("\nError recibiendo mensaje...");
printf("\n\nMensaje enviado satisfactoriamente!!!\nAck ----------> %s\n\nFinalizando..\n",&msg);
close(sd);
exit(0);
}
Proceso servidor.
#include <stdio.h>
#include <netdb.h> /* gethostbyname() necesita esta cabecera */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
int main(){
struct sockaddr_in server_addr, client_addr;
int sd, sc;
int size;
char *msg;
int msg2=1000;
sd = socket(AF_INET, SOCK_STREAM, 0);
bzero((char *)&client_addr, sizeof(client_addr));
bzero((char *)&server_addr, sizeof(server_addr));
/*asignamos direccion al socket*/
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(6969);
server_addr.sin_addr.s_addr = INADDR_ANY;
// memset(&(server_addr.sin_zero), 0, 8);
printf("\nEsperando conexión...listen ");
bind(sd,(struct sockaddr *) &server_addr, sizeof(struct sockaddr));
listen(sd, 5);
size = sizeof(client_addr);
sc = accept(sd, (struct sockaddr *)&client_addr, &size);
if(sc<0){ printf("\nSC ===============> %d",sc);exit(1);}
else printf("\nSC ===============> %d",sc);
/*recibe peticion...*/
if(read(sc,(char *)&msg, 25)==-1) perror("\nError recibiendo datos..cerrando");
else printf("\nMSG recibido/enviado => %s\n\n",&msg);
if(write(sc,(char *)&msg, 25)==-1) perror("\nError enviando datos..cerrando"); // <------- EL ERROR ESTA AQUI!!
close(sc);
printf("\nConexion finalizada...\n");
close(sd);
exit(0);
}
El cliente se conecta perfectamente al servidor y este recibe bien los datos.. pero a la hora de devolver los datos del servidor al cliente me da un error en el servidor de "Bad file descriptor"... es decir, que el descriptor usado en el write no es correcto.. no se puede usar el mismo descriptor para leer y escribir a la vez??? Pq si envio del server al cliente funciona correctamente tb. El problema es leer y escribir usando el mismo descriptor... alguna sugerencia???
He probado varias cosas, entre ellas usar send y demas pero tampoco va..
Tengo estas 2 maquinas:
P166 corriendo debian sarge
AMD Athlon64 corriendo debian sid amd64(alioth)
Si uso el p166 como server, este me arroja el Bad file descriptor como error al enviar datos al cliente despues de haber leido datos del cliente...
Si uso el athlon64 como server me arroja Socket operation on non-socket como error al enviar datos al cliente despues de haber leido datos de este..
Si ejecuto tanto cliente como servidor en el athlon64 o en el p166 me arroja el bad file descriptor..
Todo esto siempre es despues de leer de ese socket, si solo lo uso para enviar no pasa nada.. y no entiendo el pq pasa esto... ¬¬\'
S4Lu2!!!
Se trata de un proceso cliente y otro servidor corriendo en maquinas distintas..
Proceso cliente:
#include <stdio.h>
#include <netdb.h> /* gethostbyname() necesita esta cabecera */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
int main(){
struct sockaddr_in server_addr;
int sd;
char *msg;
sd = socket(AF_INET, SOCK_STREAM, 0);
/*obtenemos la direccion del servidor...*/
bzero((char *)&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(6969);
server_addr.sin_addr.s_addr = inet_addr("192.168.0.4");
// memset(&(server_addr.sin_zero), 0, 8);
/*establecemos conexión...*/
if(connect(sd,(struct sockaddr *) &server_addr, sizeof(struct sockaddr)) < 0){
error("\nError en la llamada connect");
}else printf("\nConexión establecida...");
sleep(1);
printf("\n\nIntroduce un mensaje ===> ");
scanf("%s",&msg);
if(write(sd,(char *)&msg, 25)==-1)perror("\nError enviando mensaje...");
else printf("\nMensaje enviado/recibido... %s",&msg);
strcpy((char *)&msg,"");
if(read(sd,(char *)&msg, 25)==-1) perror("\nError recibiendo mensaje...");
printf("\n\nMensaje enviado satisfactoriamente!!!\nAck ----------> %s\n\nFinalizando..\n",&msg);
close(sd);
exit(0);
}
Proceso servidor.
#include <stdio.h>
#include <netdb.h> /* gethostbyname() necesita esta cabecera */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
int main(){
struct sockaddr_in server_addr, client_addr;
int sd, sc;
int size;
char *msg;
int msg2=1000;
sd = socket(AF_INET, SOCK_STREAM, 0);
bzero((char *)&client_addr, sizeof(client_addr));
bzero((char *)&server_addr, sizeof(server_addr));
/*asignamos direccion al socket*/
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(6969);
server_addr.sin_addr.s_addr = INADDR_ANY;
// memset(&(server_addr.sin_zero), 0, 8);
printf("\nEsperando conexión...listen ");
bind(sd,(struct sockaddr *) &server_addr, sizeof(struct sockaddr));
listen(sd, 5);
size = sizeof(client_addr);
sc = accept(sd, (struct sockaddr *)&client_addr, &size);
if(sc<0){ printf("\nSC ===============> %d",sc);exit(1);}
else printf("\nSC ===============> %d",sc);
/*recibe peticion...*/
if(read(sc,(char *)&msg, 25)==-1) perror("\nError recibiendo datos..cerrando");
else printf("\nMSG recibido/enviado => %s\n\n",&msg);
if(write(sc,(char *)&msg, 25)==-1) perror("\nError enviando datos..cerrando"); // <------- EL ERROR ESTA AQUI!!
close(sc);
printf("\nConexion finalizada...\n");
close(sd);
exit(0);
}
El cliente se conecta perfectamente al servidor y este recibe bien los datos.. pero a la hora de devolver los datos del servidor al cliente me da un error en el servidor de "Bad file descriptor"... es decir, que el descriptor usado en el write no es correcto.. no se puede usar el mismo descriptor para leer y escribir a la vez??? Pq si envio del server al cliente funciona correctamente tb. El problema es leer y escribir usando el mismo descriptor... alguna sugerencia???
He probado varias cosas, entre ellas usar send y demas pero tampoco va..
Tengo estas 2 maquinas:
P166 corriendo debian sarge
AMD Athlon64 corriendo debian sid amd64(alioth)
Si uso el p166 como server, este me arroja el Bad file descriptor como error al enviar datos al cliente despues de haber leido datos del cliente...
Si uso el athlon64 como server me arroja Socket operation on non-socket como error al enviar datos al cliente despues de haber leido datos de este..
Si ejecuto tanto cliente como servidor en el athlon64 o en el p166 me arroja el bad file descriptor..
Todo esto siempre es despues de leer de ese socket, si solo lo uso para enviar no pasa nada.. y no entiendo el pq pasa esto... ¬¬\'
S4Lu2!!!
Hola:
Veo un pequeño lio con el char *msg
Dos cosas.
char *msg ya es un puntero, asi que en scanf, read, write, etc, etc, te sobra el & de delante.
Otra cosa. Para poder leer sobre msg (con read o scanf) necesitas hacerle apuntar a algún sitio con memoria para ello. Debes declarar msg como un array o bien asignarle memoria en algún momento.
char msg [1000];
o bien
char *msg;
msg = malloc (1000*sizeof(char));
Recuerda que cuando no necesites mas msg, debes liberarlo con free(msg)
El problema que te pasa es el siguiente (aparte de que char *msg esta sin inicializar): cuando haces read(), estas pasando &msg, es decir, la direccion donde esta la variable msg. El read() o el scanf() leen datos del socket o del teclado y los escriben en la memoria donde esta esa variable... y todos las demas (el descriptor de fichero entre ellos) machacándolas con los datos que llegan. Por eso te da error de descriptor de fichero a partir de que has hecho un read() o scanf().
Se bueno.
Veo un pequeño lio con el char *msg
Dos cosas.
char *msg ya es un puntero, asi que en scanf, read, write, etc, etc, te sobra el & de delante.
Otra cosa. Para poder leer sobre msg (con read o scanf) necesitas hacerle apuntar a algún sitio con memoria para ello. Debes declarar msg como un array o bien asignarle memoria en algún momento.
char msg [1000];
o bien
char *msg;
msg = malloc (1000*sizeof(char));
Recuerda que cuando no necesites mas msg, debes liberarlo con free(msg)
El problema que te pasa es el siguiente (aparte de que char *msg esta sin inicializar): cuando haces read(), estas pasando &msg, es decir, la direccion donde esta la variable msg. El read() o el scanf() leen datos del socket o del teclado y los escriben en la memoria donde esta esa variable... y todos las demas (el descriptor de fichero entre ellos) machacándolas con los datos que llegan. Por eso te da error de descriptor de fichero a partir de que has hecho un read() o scanf().
Se bueno.
