Muchachos, acá hago mi aporte. Soy nuevo así que, si me las mando, espero que me tengan paciencia.
Este programa lo fui haciendo a medida que practicaba para el final de info, básicamente el programa cliente trabaja con una lista doblemente enlazada y tiene todas las funciones que aprendí durante la cursada. El programa servidor simplemente trabaja con una lista simple y la manda por socket o pipe.
Espero que les sirva...
Cliente:
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
/* socket */
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
/* pipe (open)*/
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define PCNAME "127.0.0.1"
#define PORT 3569
#define MENU "\ningrese la opcion a realizar:\n\n1=recibir datos del servidor\t5=buscar un elemento\t9=liberar memoria\n
2=agregar elementos a la lista\t6=borrar un elemento\t10=recibir por pipe\n
3=listar los elementos\t\t7=cargar de archivo\t11=ingresar ordenado\n4=ordenar los datos\t\t8=guardar en archivo\t0=salir\n\n"
struct dato
{
char nombre[50];
int numero;
};
struct nodo
{
struct nodo *ant;
struct dato d;
struct nodo *sig;
};
void recibir (struct nodo **);
void agregar (struct nodo **);
void listar (struct nodo *);
void ordenar (struct nodo **);
void buscar (struct nodo *);
void borrar (struct nodo **);
void cargar (struct nodo **);
void guardar (struct nodo *);
void liberarmemoria (struct nodo **);
void recibirpipe (struct nodo **);
void agregar_ordenado (struct nodo **);
int main (void)
{
int o;
struct nodo *inicio=NULL;
system("clear");
printf(MENU);
scanf("%d",&o);
while(o)
{
if(o>11 || o<0)
{
printf("\nla opcion no es valida");
}
else
{
switch(o)
{
case 1: recibir(&inicio);break;
case 2: agregar(&inicio);break;
case 3: listar(inicio);break;
case 4: ordenar(&inicio);break;
case 5: buscar(inicio);break;
case 6: borrar(&inicio);break;
case 7: cargar(&inicio);break;
case 8: guardar(inicio);break;
case 9: liberarmemoria(&inicio);break;
case 10: recibirpipe(&inicio);break;
case 11: agregar_ordenado(&inicio);break;
}
}
printf(MENU);
scanf("%d",&o);
}
liberarmemoria(&inicio);
return 0;
}
/*_____________________________________________________________________________________________________________*/
void agregar (struct nodo **ppio)
{
struct nodo *p;
if(!(p=(struct nodo*) malloc(sizeof(struct nodo))))
{
printf("\nNo hay memoria suficiente, el programa terminara\n");
liberarmemoria(ppio);
exit (0);
}
printf("\ningrese un nombre: ");
__fpurge(stdin);
gets(p->d.nombre);
printf("ingrese un numero: ");
scanf("%d",&p->d.numero);
p->ant=NULL;
p->sig=*ppio;
if(*ppio)
(*ppio)->ant=p;
*ppio=p;
system("clear");
}
/*_____________________________________________________________________________________________________________*/
void listar (struct nodo *ppio)
{
struct nodo *p,*i;
if(!ppio)
{
printf("\n la lista esta vacia");
return;
}
for(p=ppio;p;p=p->sig)
{
printf("\nel nombre es: %s\nel numero es: %d\n\n",p->d.nombre,p->d.numero);
}
printf("______________________________________________________________");
//si quiero verificar los enlaces imprimo la lista al reves
for(i=ppio;i->sig;i=i->sig); //ubico a i al final de la lista
for(p=i;p;p=p->ant) //muestra la lista en otro sentido
{
printf("\nnombre: %s\nnumero: %d\n",p->d.nombre,p->d.numero);
}
printf("\n\nPresione enter p/ seguir");
__fpurge(stdin);
getchar();
system("clear");
}
/*_____________________________________________________________________________________________________________*/
void liberarmemoria (struct nodo **ppio)
{
struct nodo *p;
for(p=*ppio;p;p=*ppio)
{
*ppio=p->sig;
free(p);
}
system("clear");
}
/*_____________________________________________________________________________________________________________*/
void borrar (struct nodo **ppio)
{
struct nodo *p,*p1,*p2;
char nombre[21];
int i=0;
printf("\ningrese el nombre del nodo a borrar: ");
__fpurge(stdin);
gets(nombre);
for(p=*ppio;p;p=p->sig) //recorro la lista en busqueda del nodo
{
if((strcmp(p->d.nombre,nombre))==0) //comparo los nombres del nodo
{
i++; //este flag me sirve para ver si existe el nodo
if(p==*ppio) //si es el primer nodo
{
p1=p->sig;
if(p1) //en caso que sea el unico nodo no existe p1
p1->ant=NULL;
*ppio=p1;
free(p);
}
else
{
if(p->sig) //si no es el ultimo elemento (elemento del medio)
{
p1=p->ant;
p2=p->sig;
p2->ant=p1;
p1->sig=p2;
free(p);
}
else //si es el ultimo elemento
{
p1=p->ant;
p1->sig=NULL;
free(p);
}
}
}
}
if(!i)
{
printf("\nno se encontro el nodo con ese nombre\n\n");
}
}
/*_____________________________________________________________________________________________________________*/
void buscar (struct nodo *ppio)
{
struct nodo *p;
char nombre[21];
int i=0;
printf("\ningrese el nombre a buscar: ");
__fpurge(stdin);
gets(nombre);
for(p=ppio;p;p=p->sig)
{
if(strcmp(p->d.nombre,nombre)==0)
{
i++;
printf("\nel nombre es: %s\nel numero es: %d",p->d.nombre,p->d.numero);
}
}
if(!i)
{
printf("\nno se encontro el nombre");
}
}
/*_____________________________________________________________________________________________________________*/
void ordenar (struct nodo **ppio)
{
struct nodo *max,*aux=NULL,*p,*p1,*p2;
while(*ppio)
{
for(max=*ppio,p=*ppio;p;p=p->sig)
if(strcmp(max->d.nombre,p->d.nombre)<0)
max=p;
if(max==*ppio)
{
*ppio=max->sig; //desengancho el nodo y resuelvo enlaces en la primer lista
if(*ppio)
(*ppio)->ant=NULL;
}
else
{
if(max->sig) //si no es el ultimo (en este caso es del medio)
{
p1=max->ant;
p2=max->sig; //desengancho el nodo de la primer lista y resuelvo los enlaces
p1->sig=p2;
p2->ant=p1;
}
else //si es el ultimo nodo de la primer lista
{
p1=max->ant;
p1->sig=NULL;
}
}
max->sig=aux; //engancho el nodo en la lista auxiliar (ordenada)
max->ant=NULL;
if(aux)
aux->ant=max;
aux=max;
}
*ppio=aux;
if(*ppio)
printf("\nla lista se ordeno correctamente");
}
/*_____________________________________________________________________________________________________________*/
void cargar (struct nodo **ppio)
{
char nomarch[21];
struct nodo *p;
struct dato data;
FILE *fp;
printf("\ningrese el nombre del archivo a abrir: ");
__fpurge(stdin);
gets(nomarch);
if(!(fp=fopen(nomarch,"rb")))
{
printf("\nno se pudo abrir el archivo. Puede deberse a que no exista");
return;
}
fread(&data,sizeof(struct dato),1,fp);
while(!feof(fp))
{
if(!(p=(struct nodo *)malloc(sizeof(struct nodo))))
{
printf("\nno hay memoria suficiente");
return;
}
p->d=data;
p->ant=NULL;
p->sig=*ppio;
if(*ppio)
(*ppio)->ant=p;
*ppio=p;
fread(&data,sizeof(struct dato),1,fp);
}
printf("\nla lista fue completada con los datos del archivo");
fclose(fp);
}
/*_____________________________________________________________________________________________________________*/
void guardar (struct nodo *ppio)
{
FILE *fp;
struct nodo *p;
char nomarch[21];
printf("\ningrese el nombre del archivo: ");
__fpurge(stdin);
gets(nomarch);
if(!(fp=fopen(nomarch,"wb")))
{
printf("\nno se pudo abrir el archivo.");
return;
}
for(p=ppio;p;p=p->sig)
{
fwrite(&(p->d),sizeof(struct dato),1,fp);
}
fclose(fp);
}
/*_____________________________________________________________________________________________________________*/
void recibir (struct nodo **ppio)
{
struct nodo *p;
struct dato data;
struct sockaddr_in direccion;
struct hostent *serv;
int fdcli,con,elem;
fdcli=socket(AF_INET,SOCK_STREAM,0);
serv=gethostbyname(PCNAME);
direccion.sin_port=htons(PORT);
direccion.sin_family=AF_INET;
direccion.sin_addr=*((struct in_addr *) serv->h_addr);
bzero(&direccion.sin_zero,8);
con=connect(fdcli,(struct sockaddr *)&direccion,sizeof(direccion));
if(con==-1)
{
printf("\nhubo un error en la conexion, vuelva a intentar");
return;
}
elem=read(fdcli,&data,sizeof(data));
while(elem>0)
{
if(!(p=(struct nodo *)malloc(sizeof(struct nodo))))
{
printf("\nno hay memoria suficiente");
return;
}
p->d=data;
p->ant=NULL;
p->sig=*ppio;
if(*ppio)
(*ppio)->ant=p;
*ppio=p;
elem=read(fdcli,&data,sizeof(data));
}
close(fdcli);
}
/*_____________________________________________________________________________________________________________*/
void recibirpipe (struct nodo **ppio)
{
int pipe,recibido;
struct nodo *p;
struct dato data;
pipe=mkfifo("pipe",0666);
pipe=open("pipe",O_RDONLY);
recibido=read(pipe,&data,sizeof(data));
while(recibido>0)
{
if(!(p=(struct nodo *)malloc(sizeof(struct nodo))))
{
printf("no hay memoria suficiente\n");
return;
}
p->d=data;
p->ant=NULL;
p->sig=*ppio;
if(*ppio)
(*ppio)->ant=p;
*ppio=p;
recibido=read(pipe,&data,sizeof(data));
}
close(pipe);
printf("la transferencia se realizo con exito, presione una tecla");
__fpurge(stdin);
getchar();
}
/*_____________________________________________________________________________________________________________*/
void agregar_ordenado (struct nodo **ppio)
{
struct nodo *p,*pant,*psig;
int flag=1;
// ordenar(ppio); //para ingresar ordenado la lista tiene que estar ordenada previamente
if(!(p=(struct nodo*)malloc(sizeof(struct nodo))))
{
printf("\nno hay memoria suficiente, el programa terminara.\n");
liberarmemoria(ppio);
exit (0);
}
printf("\nIngrese el nombre: ");
__fpurge(stdin);
gets(p->d.nombre);
printf("Ingrese un numero: ");
scanf("%d",&p->d.numero);
for(psig=*ppio,pant=NULL;psig && flag;) //loop para encontrar la posicion, puede que encuentren una forma
{ //mas facil para resolver esto. Yo me encontre con el problema de que
if(psig) //si ponia la funcion strcmp en el for llegaba un momento que se
{ //comparaba un string con un NULL y me tiraba violacion de segmento.
if(strcmp(p->d.nombre,psig->d.nombre)<0) //Por esto es que hice una cosa medio rara con el flag, espero que se
flag=0; //entienda.
else
{
pant=psig;
psig=psig->sig;
}
}
}
if(pant==NULL && psig==NULL) //unico nodo de la lista
{
p->ant=NULL;
p->sig=NULL;
*ppio=p;
}
else //resto de los nodos
{
p->ant=pant;
p->sig=psig;
if(pant)
pant->sig=p;
if(psig)
psig->ant=p;
if(pant==NULL && psig)
*ppio=p;
}
}
[u]Servidor[/u]
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
/* socket */
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
/* pipe */
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#define PORT 3569
struct dato
{
char nombre[50];
int numero;
};
struct nodo
{
struct dato d;
struct nodo *next;
};
void insdata (struct nodo **);
void envia (struct nodo *);
void borrar (struct nodo *);
void enviapipe (struct nodo *);
int main (void)
{
struct nodo *inicio=NULL;
int opcion;
insdata(&inicio);
printf("como desea mandar los datos?: 1-socket\t2-pipe\n");
scanf("%d",&opcion);
if(opcion==1)
envia(inicio);
else
enviapipe(inicio);
borrar(inicio);
return 0;
}
/*_____________________________________________________________________________________________________________*/
void insdata(struct nodo **ppio) //ingresa el nombre al principio
{
struct nodo *p;
char nombre[21];
printf("\ningrese nombre: ");
__fpurge(stdin);
gets(nombre);
while(strcmp(nombre,"0"))
{
if(!(p=(struct nodo *)malloc(sizeof(struct nodo))))
{
printf("no hay memoria suficiente");
borrar(*ppio);
exit(0);
}
strcpy(p->d.nombre,nombre);
printf("ingrese el numero: ");
scanf("%d",&p->d.numero);
p->next=*ppio;
*ppio=p;
printf("\ningrese nombre: ");
__fpurge(stdin);
gets(nombre);
}
}
/*_____________________________________________________________________________________________________________*/
void envia (struct nodo *ppio) //envia la list por socket
{
struct dato item;
struct nodo *p;
struct sockaddr_in my_addr, their_addr;
unsigned int fdserv,fdcon;
unsigned int e=sizeof(their_addr);
fdserv=socket(AF_INET,SOCK_STREAM,0);
my_addr.sin_family=AF_INET;
my_addr.sin_port=htons(PORT);
my_addr.sin_addr.s_addr=INADDR_ANY;
bzero(&my_addr.sin_zero,8);
bind(fdserv,(struct sockaddr *)&my_addr,e);
listen(fdserv,1);
fdcon=accept(fdserv,(struct sockaddr *)&their_addr,&e);
for(p=ppio;p;p=p->next)
{
item=p->d;
write (fdcon,&item,(sizeof (item)));
}
close(fdcon);
close(fdserv);
}
/*_____________________________________________________________________________________________________________*/
void enviapipe (struct nodo *ppio)
{
int pipe;
struct nodo *p;
struct dato data;
if((pipe=open("pipe",O_WRONLY))==-1)
{
printf("el pipe no existia, se creara uno nuevo\n");
if((pipe=mkfifo("pipe",0666))==-1)
{
printf("no se pudo crear el pipe. El programa termina\n");
exit (0);
}
}
printf("el pipe se abrio correctamente, enviando datos\n");
for(p=ppio;p!=NULL;p=p->next)
{
printf("s\n");
data=p->d;
write(pipe,&data,sizeof(data));
}
close(pipe);
}
void borrar (struct nodo *ppio) //borra la lista enviada
{
struct nodo *p;
for(p=ppio;p;p=ppio)
{
ppio=p->next;
free(p);
}
}