249 lines
10 KiB
C
249 lines
10 KiB
C
/**************************************************************************/
|
|
/* */
|
|
/* P1 - MI amb sockets TCP/IP - Part I */
|
|
/* Fitxer p2p.c que implementa la interfície aplicació-usuari de */
|
|
/* l'aplicació de MI, sobre la capa d'aplicació de MI (fent crides a la */
|
|
/* interfície de la capa MI -fitxers mi.c i mi.h-). */
|
|
/* */
|
|
/* Autors: Marc Cané Salamià, Enric Rodríguez Galán */
|
|
/* */
|
|
/**************************************************************************/
|
|
|
|
|
|
/* Inclusió de llibreries, p.e. #include <stdio.h> o #include "meu.h" */
|
|
/* Incloem "MIp1v4-mi.h" per poder fer crides a la interfície de MI */
|
|
#include "MIp2-mi.h"
|
|
#include "../nodelumi2/MIp2-lumi.h"
|
|
|
|
#include "stdio.h"
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
|
|
/* Definició de constants, p.e., #define MAX_LINIA 150 */
|
|
|
|
#define MAX_MISSATGE 300
|
|
#define IP_LENGTH 16
|
|
#define TECLAT 0
|
|
#define MARCA_FI "/end"
|
|
|
|
int main(int argc,char *argv[])
|
|
{
|
|
/* Declaració de variables, p.e., int n; */
|
|
|
|
/*int sesc, scon, slumi; //socket descriptor dels sockets
|
|
int port=0, port_loc, port_rem; //port: farà de port local o remot segons la situació. Les variables port_loc i port_rem son per claretat de codi.
|
|
char IPloc[IP_LENGTH], IPrem[IP_LENGTH]; //IPs local i remota
|
|
char adrLUMIloc[MAX_LEN_DOMINI+MAX_USER_NICK+1], adrLUMIrem[MAX_LEN_DOMINI+MAX_USER_NICK+1];
|
|
char nickname_l[MAX_MISSATGE], nickname_r[MAX_MISSATGE]; //Nicknames local i remot
|
|
char vols_continuar; //Eleccio de l'usuari
|
|
int usuari_vol_conversa=1, connectat = 0; //Boolea per saber si l'usuari vol seguir parlant*/
|
|
|
|
int sesc, scon, slumi, desc; //descriptors dels sockets
|
|
int port_loc, port_rem; //port: farà de port local o remot segons la situació. Les variables port_loc i port_rem son per claretat de codi.
|
|
char IPloc[IP_LENGTH], IPrem[IP_LENGTH], IPnode[IP_LENGTH]; //IPs local i remota i del node
|
|
char adrLUMIloc[MAX_LEN_DOMINI+MAX_USER_NICK+1], adrLUMIrem[MAX_LEN_DOMINI+MAX_USER_NICK+1];
|
|
char nickname_l[MAX_MISSATGE], nickname_r[MAX_MISSATGE]; //Nicknames local i remot
|
|
char domini_l[MAX_LEN_DOMINI], domini_r[MAX_LEN_DOMINI];
|
|
char resposta[MAX_MISSATGE_PLUMI+1];
|
|
char vols_continuar; //Eleccio de l'usuari
|
|
int fitxer_log;
|
|
int usuari_vol_conversa=1, connectat = 0, res; //Boolea per saber si l'usuari vol seguir parlant
|
|
int llistaDesc[3];
|
|
|
|
/* Expressions, estructures de control, crides a funcions, etc. */
|
|
printf("Entra la teva @MI: ");
|
|
scanf("%s", adrLUMIloc);
|
|
printf("Quin nom d'usuari vols fer servir: ");
|
|
scanf("%s", nickname_l);
|
|
|
|
//LUMI_DescodificarAdreca(adrLUMIloc,nickname_l,domini_l);
|
|
|
|
if ((slumi = LUMI_InicialitzarAgent("0.0.0.0",0, &fitxer_log, adrLUMIloc, IPnode)) < 0){
|
|
//Apagar tot
|
|
close(slumi);
|
|
return 1;
|
|
}
|
|
|
|
res = LUMI_EnviaPeticioRegistre(slumi, adrLUMIloc);
|
|
if (res == 0) printf("S'ha rebut un missatge de confirmacio inesperat\n");
|
|
else if (res == -1) printf("Error a l'hora d'enviar la peticio de registre\n");
|
|
else if (res == -2) printf("Format del missatge de registre enviat incorrecte\n");
|
|
else if (res == -3) printf("L'usuari que has indicat no existeix\n");
|
|
else if (res == -4) printf("L'usuari que has indicat ja esta registrat\n");
|
|
else if (res == -5) printf("Temps d'espera de peticio de registre esgotat\n");
|
|
else if (res == -6) printf("Format del missatge de resposta incorrecte\n");
|
|
else printf("Error desconegut\n");
|
|
|
|
while(usuari_vol_conversa){
|
|
|
|
connectat = 0;
|
|
|
|
if ((sesc = MI_IniciaEscPetiRemConv(0)) == -1) return 1;
|
|
|
|
if (MI_ObtenirInfoServidor(sesc,IPloc,&port_loc) == -1) return 1;
|
|
|
|
//printf("\nLa IP necessaria per comunicar-se amb aquest terminal es: %s\nEl port assignat per comunicar-se amb aquest terminal es: %i\n\n", IPloc, port_loc);
|
|
|
|
llistaDesc[0]=TECLAT;
|
|
llistaDesc[1]=sesc;
|
|
llistaDesc[2]=slumi;
|
|
|
|
printf("Si vols iniciar conversa amb algu, entra la seva @MI, altrament espera:\n");
|
|
|
|
while(connectat==0){
|
|
desc = HaArribatAlgunaCosaEnTemps(llistaDesc, 3, 0);
|
|
if(desc == slumi){
|
|
res = LUMI_RepLiniaDe(slumi, NULL, NULL, resposta, sizeof(resposta));
|
|
if(res==-2) printf("S'ha rebut una linia mal formatada\n");
|
|
else if(res<=0) printf("S'ha produit un error al rebre un missatge de LUMI\n");
|
|
res = LUMI_DescodificarMissatge(resposta[0], resposta, adrLUMIrem, NULL, NULL);
|
|
if(res==-1) printf("Error al descodificar un missatge LUMI\n");
|
|
|
|
if (resposta[0] == 'S') {
|
|
//printf("En markus ha respos a la peticio S\n");
|
|
res = LUMI_EnviaRespostaServeiLocalitzacio(slumi, adrLUMIrem, IPloc, port_loc);
|
|
if(res<=0) printf("Error al respondre peticio de localitzacio\n");
|
|
}
|
|
}
|
|
else{
|
|
if (desc == -1){ //Si hi ha algun problema
|
|
printf("Error al escoltar\n");
|
|
MI_AcabaEscPetiRemConv(sesc);
|
|
return 1;
|
|
}
|
|
else if(desc == TECLAT){ //Client
|
|
|
|
scanf("%s", adrLUMIrem);
|
|
|
|
if (strcmp(adrLUMIrem, "/end")!=0) {
|
|
|
|
res = LUMI_EnviaPeticioLocalitzacio(slumi, adrLUMIloc, adrLUMIrem, IPrem, &port_rem);
|
|
|
|
//printf("Nanu: %s, amb ip: %s i port %i, intenta parlar amb %s, amb ip: %s i port: %i\n", nickname_l, IPloc, port_loc, nickname_r, IPrem, port_rem);
|
|
|
|
if (res == 1) { //ha arribat una C
|
|
scon = MI_DemanaConv(IPrem, port_rem, IPloc, &port_loc, nickname_l, nickname_r);
|
|
|
|
if (scon == -1) return 1;
|
|
//printf("YES! Nanu: %s, amb ip: %s i port %i, intenta parlar amb %s, amb ip: %s i port: %i\n", nickname_l, IPloc, port_loc, nickname_r, IPrem, port_rem);
|
|
connectat = 1;
|
|
}
|
|
else {
|
|
if (res == 0) printf("S'ha rebut un missatge de confirmacio inesperat\n");
|
|
else if (res == -1) printf("Error a l'hora d'enviar la peticio de localitzacio\n");
|
|
else if (res == -2) printf("Format del missatge de localitzacio enviat incorrecte\n");
|
|
else if (res == -3) printf("L'usuari que has indicat no existeix\n");
|
|
else if (res == -4) printf("L'usuari que has indicat esta fora de linia\n");
|
|
else if (res == -5) printf("Temps d'espera de peticio de localitzacio esgotat\n");
|
|
else if (res == -6) printf("Format del missatge de resposta incorrecte\n");
|
|
else if (res == -7) printf("L'usuari que has indicat esta ocupat. Prova mes tard\n");
|
|
else printf("Error desconegut\n");
|
|
}
|
|
} else{
|
|
MI_AcabaEscPetiRemConv(sesc);
|
|
printf("Fins aviat!\n");
|
|
return 0;
|
|
}
|
|
}
|
|
else{ //Servidor (sesc)
|
|
if ((scon = MI_AcceptaConv(sesc, IPrem, &port_rem, IPloc, &port_loc, nickname_l, nickname_r)) == -1) return 1;
|
|
|
|
//printf()
|
|
printf("Has iniciat una conversa amb %s\n", nickname_r);
|
|
connectat = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
MI_AcabaEscPetiRemConv(sesc); //Deixem d'escoltar, ja tenim un parell d'usuaris connectats
|
|
|
|
llistaDesc[1]=scon;
|
|
|
|
printf("\nConnexio establerta entre %s i %s\n\n", nickname_l, nickname_r);
|
|
printf("Dades de l'usuari local: \n\t @MI: %s \n\t IP: %s \n\t Port: %i \n\n", adrLUMIloc, IPloc, port_loc);
|
|
printf("Dades de l'usuari remot: \n\t @MI: %s \n\t IP: %s \n\t Port: %i \n\n", adrLUMIrem, IPrem, port_rem);
|
|
|
|
int canal, fi = 0; //fi ens indica si s'ha de parar la execució del programa o no
|
|
char buffer[MAX_MISSATGE]; //Buffer on guardarem les linies que anem rebent
|
|
|
|
while(!fi){
|
|
|
|
canal = HaArribatAlgunaCosaEnTemps(llistaDesc, 3, 0); //Obtenim el canal pel qual esta arribant una linia
|
|
|
|
if(canal == TECLAT){ //Si el canal és teclat significa que nosaltres li volem dir algo al usuari remot
|
|
|
|
int bytes_llegits = read(TECLAT,buffer,sizeof(buffer)); //Llegim el que li volem enviar i ho fiquem a un buffer
|
|
buffer[bytes_llegits-1] = '\0'; //Per protocol convertim aquesta tira entrada en una "String" de C
|
|
|
|
if (bytes_llegits == -1) perror("Error al entrar per teclat");
|
|
|
|
if(strcmp(buffer,MARCA_FI) == 0){ //Pot ser que s'hagi indicat que es vol acabar, en aquest cas no s'envia cap linia al usuari remot
|
|
MI_AcabaConv(scon); //Tenca la conversa entre els dos
|
|
fi = 1;
|
|
}
|
|
else MI_EnviaLinia(scon,buffer); //Si no és la marca de fi li enviem el que s'ha escrit per teclat
|
|
|
|
}
|
|
else if(canal == scon){ //Si el canal és scon significa que hem rebut una linia de l'usuari remot
|
|
|
|
int estat_linia; //Variable que ens indica l'estat de la linia que connecta els dos usuaris, no confondre ammb la linia enviada
|
|
|
|
estat_linia = MI_RepLinia(scon,buffer); //Es rep la linia enviada i es guarda al buffer
|
|
|
|
if (estat_linia == -1){ //Si hi ha algun error en la recepció
|
|
perror("Error: s'ha tancat inesperadament la connexio");
|
|
fi = 1;
|
|
MI_AcabaConv(scon);
|
|
}
|
|
else if (estat_linia == -2) { //L'altre ha finalitzat la conversa
|
|
fi = 1;
|
|
MI_AcabaConv(scon);
|
|
printf("L'usuari remot ha finalitzat la connexio\n");
|
|
}
|
|
else printf("%s: %s\n", nickname_r, buffer); //Si no hi ha cap problema i no s'ha acabat la conversa mostrem la linia rebuda per pantalla
|
|
|
|
} else if (canal == slumi){
|
|
LUMI_RepLiniaDe(slumi, NULL, NULL, resposta, sizeof(resposta));
|
|
char adrDESCrem[sizeof(adrLUMIrem)];
|
|
LUMI_DescodificarMissatge(resposta[0], resposta, adrDESCrem, NULL, NULL);
|
|
|
|
if (resposta[0] == 'S') {
|
|
LUMI_EnviaResposta(slumi, 'C', adrDESCrem, IPnode, 0); //li passem port 0 per indicar que es un socket UDP "connectat"
|
|
}
|
|
}
|
|
if (canal == -1){ //Si el canal rebut és -1 significa que hi ha algun error
|
|
perror("Error desconegut (select)");
|
|
MI_AcabaConv(scon);
|
|
}
|
|
}
|
|
|
|
printf("Vols parlar amb algu mes? (s/n)\n");
|
|
scanf(" %c", &vols_continuar);
|
|
|
|
usuari_vol_conversa = (vols_continuar == 's');
|
|
}
|
|
|
|
res = LUMI_EnviaPeticioDesregistre(slumi);
|
|
|
|
if (res == 0) printf("S'ha rebut un missatge de confirmacio inesperat\n");
|
|
else if (res == -1) printf("Error a l'hora d'enviar la peticio de desregistre\n");
|
|
else if (res == -2) printf("Format del missatge de desregistre enviat incorrecte\n");
|
|
else if (res == -3) printf("L'usuari que has indicat no existeix\n");
|
|
else if (res == -4) printf("L'usuari que has indicat ja esta desregistrat\n");
|
|
else if (res == -5) printf("Temps d'espera de peticio de desregistre esgotat\n");
|
|
else if (res == -6) printf("Format del missatge de resposta incorrecte\n");
|
|
else printf("Error desconegut\n");
|
|
|
|
LUMI_Desconnecta(slumi);
|
|
printf("Fins aviat!\n");
|
|
|
|
return 0;
|
|
}
|