/**************************************************************************/ /* */ /* 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 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 #include #include #include #include #include #include #include #include /* 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; }