Linux - problema con socket

 
Vista:

problema con socket

Publicado por Nock (2 intervenciones) el 04/04/2007 19:15:21
Buenas, quiero realizar una comunicacion orientada a conexion con un cliente y varios servidores.
Primero para ver como funciona lo he intentado con uno, y ni siquiera me funciona.
En el servidor me da un error en el recv "transport endpoint is not connected".

El codigo del cliente es:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void error (char *mesg);
int main(int argc, char * argv[])
{
int sockfd, long_dir_serv;
struct sockaddr_in dir_cli, dir_serv;
struct r_p{
char nombre;
char proceso;
}peticion;
struct r_r{
char nombre;
int ocupado;
char proceso;
char *mensaje;
}respuesta;

//Miramos si el numero de argumentos esta bien
if(argc!=3){
puts("\nIntroducir la direccion y el puerto del servidor como parametros");
exit(1);
}

if((sockfd=socket(AF_INET, SOCK_STREAM,0))==-1)
error("\nERROR AL CREAR EL SOCKET");

dir_serv.sin_port=htons(atoi(argv[2]));
dir_serv.sin_addr.s_addr=inet_addr(argv[1]);
dir_serv.sin_family=AF_INET;
long_dir_serv = sizeof(dir_serv);

//conect(socket, direccion del servidor y puertos, longitud de la direccion)
if(connect(sockfd, (struct sockaddr*)&dir_serv, long_dir_serv)==-1)
error("\nERROR AL CONECTAR CON EL SOCKET");

printf("\n¿Que nombre de proceso eres?");
scanf("%c",peticion.proceso);

printf("\n¿A que recurso quieres acceder (A, B, C o D)?");
scanf("%c",peticion.nombre);

if(send(sockfd, &peticion, sizeof(peticion), 0)==-1)
error("\nERROR EN EL ENVIO");

if(recv(sockfd, &respuesta, (sizeof(respuesta)-1), 0)==-1)
error("\nERROR EN RECEPCION");

if (respuesta.mensaje == '\0')
printf("\nEl recurso solicitado no existe");
else
if(respuesta.ocupado == 1)
printf("\nEl proceso %c ha pedido el recurso %c y esta ocupado",respuesta.proceso, respuesta.nombre);
else
printf("\nEl proceso %c ha pedido el recurso %c y esta libre",respuesta.proceso, respuesta.nombre);

close(sockfd);
exit(0);
}

El codigo del servidor es:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void error (char *mesg);
int main (int argc, char * argv[])
{
int sockfd, long_dir_cli;
int conexionmax = 4; //numero maximo de clientes distintos
struct sockaddr_in dir_cli, dir_serv;
struct tnodo{
char proceso; //nombre del proceso
struct tnodo *sig; //puntero al siguiente (ver por que no funciona
}nodo;
struct recur{
char nombre; //nombre del recurso
int ocupado; //si esta ocupado o no
char proceso; //nombre del proceso que lo ocupa
struct tnodo *cabecera; //cabecera a la lista de espera
}recurso;
struct r_p{
char nombre; //nombre del recurso
char proceso; //nombre del proceso que pide
}peticion;
struct r_r{
char nombre; //nombre del recurso
int ocupado; //si esta ocupado
char proceso; //a que proceso va
char *mensaje;
}respuesta;

struct recur recursostotales[3];
//Relleno los recursos
recursostotales[0].nombre = 'A';
recursostotales[0].ocupado = 0;
recursostotales[0].cabecera = '\0';

recursostotales[1].nombre = 'B';
recursostotales[1].ocupado = 0;
recursostotales[1].cabecera = '\0';

recursostotales[2].nombre = 'C';
recursostotales[2].ocupado = 0;
recursostotales[2].cabecera = '\0';

recursostotales[3].nombre = 'D';
recursostotales[3].ocupado = 0;
recursostotales[3].cabecera = '\0';

//Miramos si el numero de argumentos introducido esta bien
if (argc!=3){
puts("\nIntroducir la direccion y el puerto del servidor como parametros");
exit(1);
}

//socket(dominio, tipo, protocolo)
//AF_INET
//SOCK_STREAM orientado a la conexion (TCP)
//Si devuelve -1 es que hay error
if ((sockfd = socket (AF_INET, SOCK_STREAM,0))==-1)
error("\nERROR AL CREAR EL SOCKET");

dir_serv.sin_port=htons(atoi(argv[2]));
dir_serv.sin_addr.s_addr=inet_addr(argv[1]);
dir_serv.sin_family=AF_INET;

//bind(socket, direccion, longitud)
//socket es el socket abierto antes en el if de arriba
//direccion es mi direccion
//longitud es el tamaño de los datos de la direccion
if (bind(sockfd, (struct sockaddr*) &dir_serv, sizeof(dir_serv))==-1)
error("\ERROR AL ENLAZAR EL SOCKET");

long_dir_cli=sizeof(struct sockaddr_in);

//listen(socket, numero de conexiones aceptadas)
if(listen(sockfd, conexionmax)==-1)
error("\nERROR AL ESCUCHAR");

//accept(socket, nodo que nos conecta y desde que puerto, tamaño de lo anterior)
if(accept(sockfd,(struct sockaddr*)&dir_cli, &long_dir_cli)==-1)
error("\nERROR AL ACEPTAR");

//recv(socket, mensaje, tamañomen, opcion)
//socket es el socket que recibimos
//mensaje el mensaje que recibimos
//tamañomen el tamaño del mensaje
//opcion de momento lo dejamos en 0
if(recv(sockfd, &peticion, sizeof(peticion),0)==-1)
error("\nERROR AL RECIBIR PETICION DEL CLIENTE");

//hacemos las comprobaciones oportunas

switch(peticion.nombre)
{
case 'A':
respuesta.ocupado = recursostotales[0].ocupado;
respuesta.nombre = 'A';
respuesta.proceso=peticion.proceso;
respuesta.mensaje = '\0';
if (recursostotales[0].ocupado == 0)
recursostotales[0].ocupado=1;
break;
case 'B':
respuesta.ocupado = recursostotales[1].ocupado;
respuesta.nombre='B';
respuesta.proceso=peticion.proceso;
respuesta.mensaje = '\0';
if(recursostotales[1].ocupado == 0)
recursostotales[1].ocupado = 1;
break;
case 'C':
respuesta.ocupado = recursostotales[2].ocupado;
respuesta.nombre='C';
respuesta.proceso=peticion.proceso;
respuesta.mensaje='\0';
if(recursostotales[2].ocupado == 0)
recursostotales[2].ocupado = 1;
break;
case'D':
respuesta.ocupado = recursostotales[3].ocupado;
respuesta.nombre='D';
respuesta.proceso=peticion.proceso;
respuesta.mensaje='\0';
if(recursostotales[3].ocupado==0)
recursostotales[3].ocupado = 1;
break;
default: respuesta.mensaje = "No existe ese proceso";

}

if(send(sockfd, &respuesta, sizeof(respuesta),0)==-1)
error("\nERROR AL ENVIAR DATOS AL CLIENTE");

}
void error(mesg)
char *mesg;
{
perror(mesg);
exit(1);
}

Gracias de antemano
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:problema con socket

Publicado por Tom (35 intervenciones) el 09/04/2007 10:28:38
Bueno, debes buscar ejemplos o tutoriales por la red (hay muchos) para aprender cómo funcionan los sockets.

El server socket no se usa para leer o escribir en él. Si miras el man de accept, verás que el resultado de esta función es otro socket, ya conectado con el cliente. Este socket es el que debes usar desde el servidor para comunicarte con el cliente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:problema con socket

Publicado por Nock (2 intervenciones) el 09/04/2007 12:56:36
Muchas gracias.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:problema con socket

Publicado por zkoria (2 intervenciones) el 23/08/2007 17:27:26
Haber chaketas...

Estuve revisando tu codiguillo... y ya lo hice funcionar. Recomiendo le eches un vistazo

-Al man de accept().
-La declaracion de variables tipo estructura
- y demas pendejadillas...

Como intento no estuvo mal pero...

Lamento la tardanza en la contestación pero tiene rato ke no entraba a este antrrillo que hace tiempo me aburre... en fin. IGUAL Y LE SIRVE A OTRO WE...

ThePowerThisInMind...


=====
client.c
=====
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void error (char *mesg);
int main(int argc, char * argv[])
{
int sockfd, long_dir_serv;
struct sockaddr_in dir_cli, dir_serv;

struct r_p{
char nombre;
char proceso;
};

struct r_p mi_peticion;

struct r_r{
char nombre;
int ocupado;
char proceso;
char *mensaje;
}respuesta;
//Miramos si el numero de argumentos esta bien
if(argc!=3){
puts("\nIntroducir la direccion y el puerto del servidor como parametros");
exit(1);
}

if((sockfd=socket(AF_INET, SOCK_STREAM,0))==-1)
error("\nERROR AL CREAR EL SOCKET");

dir_serv.sin_port=htons(atoi(argv[2]));
dir_serv.sin_addr.s_addr=inet_addr(argv[1]);
dir_serv.sin_family=AF_INET;
long_dir_serv = sizeof(dir_serv);

//conect(socket, direccion del servidor y puertos, longitud de la direccion)
if(connect(sockfd, (struct sockaddr*)&dir_serv, long_dir_serv)==-1)
error("\nERROR AL CONECTAR CON EL SOCKET");

/*
printf("\n¿Que nombre de proceso eres?");
scanf("%c",mi_peticion.proceso);

printf("\n¿A que recurso quieres acceder (A, B, C o D)?");
scanf("%c",mi_peticion.nombre);
*/
mi_peticion.proceso ='p';
printf("zkoria 1\n");

if(send(sockfd, &mi_peticion, sizeof(struct r_p), 0)==-1)
error("\nERROR EN EL ENVIO");

printf("zkoria 2\n");

if(recv(sockfd, &respuesta, (sizeof(respuesta)-1), 0)==-1)
error("\nERROR EN RECEPCION");

printf("zkoria 3\n");

if (respuesta.mensaje == '\0')
printf("\nEl recurso solicitado no existe");
else
if(respuesta.ocupado == 1)
printf("\nEl proceso %c ha pedido el recurso %c y esta ocupado",respuesta.proceso, respuesta.nomb
re);
else
printf("\nEl proceso %c ha pedido el recurso %c y esta libre",respuesta.proceso, respuesta.nombre
);

close(sockfd);
exit(0);
}



======
server.c
======
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

void error (char *mesg);
int main (int argc, char * argv[])
{
int sockfd, long_dir_cli;
int conexionmax = 4; //numero maximo de clientes distintos
struct sockaddr_in dir_cli, dir_serv;
struct tnodo{
char proceso; //nombre del proceso
struct tnodo *sig; //puntero al siguiente (ver por que no funciona
}nodo;

struct recur{
char nombre; //nombre del recurso
int ocupado; //si esta ocupado o no
char proceso; //nombre del proceso que lo ocupa
struct tnodo *cabecera; //cabecera a la lista de espera
}recurso;

struct r_p{
char nombre; //nombre del recurso
char proceso; //nombre del proceso que pide
};

struct r_p mi_peticion;

struct r_r{
char nombre; //nombre del recurso
int ocupado; //si esta ocupado
char proceso; //a que proceso va
char *mensaje;
}respuesta;

struct recur recursostotales[3];
//Relleno los recursos
recursostotales[0].nombre = 'A';
recursostotales[0].ocupado = 0;
recursostotales[0].cabecera = '\0';

recursostotales[1].nombre = 'B';
recursostotales[1].ocupado = 0;
recursostotales[1].cabecera = '\0';

recursostotales[2].nombre = 'C';
recursostotales[2].ocupado = 0;
recursostotales[2].cabecera = '\0';

recursostotales[3].nombre = 'D';
recursostotales[3].ocupado = 0;
recursostotales[3].cabecera = '\0';

//Miramos si el numero de argumentos introducido esta bien
if (argc!=3){
puts("\nIntroducir la direccion y el puerto del servidor como parametros");
exit(1);
}

//socket(dominio, tipo, protocolo)
//AF_INET
//SOCK_STREAM orientado a la conexion (TCP)
//Si devuelve -1 es que hay error
if ((sockfd = socket (AF_INET, SOCK_STREAM,0))==-1)
error("\nERROR AL CREAR EL SOCKET");

dir_serv.sin_port=htons(atoi(argv[2]));
dir_serv.sin_addr.s_addr=inet_addr(argv[1]);
dir_serv.sin_family=AF_INET;

//bind(socket, direccion, longitud)
//socket es el socket abierto antes en el if de arriba
//direccion es mi direccion
//longitud es el tamañe los datos de la direccion
if (bind(sockfd, (struct sockaddr*) &dir_serv, sizeof(dir_serv))==-1)
error("\ERROR AL ENLAZAR EL SOCKET");
long_dir_cli=sizeof(struct sockaddr_in);

//listen(socket, numero de conexiones aceptadas)
if(listen(sockfd, conexionmax)==-1)
error("\nERROR AL ESCUCHAR");

//accept(socket, nodo que nos conecta y desde que puerto, tamañe lo anterior)

int clientelito;
clientelito = accept(sockfd,(struct sockaddr*)&dir_cli, &long_dir_cli);
if(clientelito == -1)
error("\nERROR AL ACEPTAR");

//recv(socket, mensaje, tamañn, opcion)
//socket es el socket que recibimos
//mensaje el mensaje que recibimos
//tamañn el tamañel mensaje
//opcion de momento lo dejamos en 0

printf("clientelito: %d\n", clientelito);

if(recv(clientelito, &mi_peticion, sizeof(struct r_p),0)==-1)
error("\nERROR AL RECIBIR PETICION DEL CLIENTE");

//hacemos las comprobaciones oportunas
switch(mi_peticion.nombre)
{
case 'A':
respuesta.ocupado = recursostotales[0].ocupado;
respuesta.nombre = 'A';
respuesta.proceso=mi_peticion.proceso;
respuesta.mensaje = '\0';
if (recursostotales[0].ocupado == 0)
recursostotales[0].ocupado=1;
break;
case 'B':
respuesta.ocupado = recursostotales[1].ocupado;
respuesta.nombre='B';
respuesta.proceso=mi_peticion.proceso;
respuesta.mensaje = '\0';
if(recursostotales[1].ocupado == 0)
recursostotales[1].ocupado = 1;
break;
case 'C':
respuesta.ocupado = recursostotales[2].ocupado;
respuesta.nombre='C';
respuesta.proceso=mi_peticion.proceso;
respuesta.mensaje='\0';
if(recursostotales[2].ocupado == 0)
recursostotales[2].ocupado = 1;
break;
case'D':
respuesta.ocupado = recursostotales[3].ocupado;
respuesta.nombre='D';
respuesta.proceso=mi_peticion.proceso;
respuesta.mensaje='\0';
if(recursostotales[3].ocupado==0)
recursostotales[3].ocupado = 1;
break;
default: respuesta.mensaje = "No existe ese proceso";

}

if(send(clientelito, &respuesta, sizeof(respuesta),0)==-1)
error("\nERROR AL ENVIAR DATOS AL CLIENTE");

}
void error(mesg)
char *mesg;
{
perror(mesg);
exit(1);
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar