codice:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <fcntl.h>
#include "ricercauser.h"
#include <malloc.h>
#include <pthread.h>
typedef struct utente utente;
typedef utente *List;
typedef struct utente{
int id;
char* utente;
char* password;
int gruppo; //0 se non partecipa a nessun gruppo
List next;
int sendport;
int recvport;
};
/* gcc -o main -pthread main.c */
//Variabili Globali
List head=NULL;
int id=0;
//Dichiarazioni di funzioni
int CreaSocketrecv(int Porta);
void ChiudiSocket(int sock);
int login(char* buffer);
char* stringcmd(char* buffer);
void* my_thread_listen(int DescrittoreSocketrecv);
int CreaSocketsend(char* Destinazione, int Porta);
void SpedisciMessaggio(int sock, char* Messaggio);
void onlysend(char* msg,int port);
List newNode (int id,char* utente,char* pass,int gruppo,int sendport,int recvport);
List insertHead(int id,char* utente,char* pass,int gruppo,int sendport,int recvport,List head);
List newNode (int id,char* utente,char* pass,int gruppo,int sendport,int recvport){
List head =(List)malloc(sizeof(*head));
head->utente=utente;
head->password=pass;
head->id=id;
head->gruppo=gruppo;
head->sendport=sendport;
head->recvport=recvport;
head->next=NULL;
return head;
}
List insertHead(int id,char* utente,char* pass,int gruppo,int sendport,int recvport,List head){
List ptr=(List)malloc(sizeof(*head));
ptr->utente=utente;
ptr->password=pass;
ptr->id=id;
ptr->gruppo=gruppo;
ptr->sendport=sendport;
ptr->recvport=recvport;
ptr->next=head;
return ptr;
}
int CreaSocketrecv(int Porta)
{
int sock,errore;
struct sockaddr_in temp;
//Creazione socket
sock=socket(AF_INET,SOCK_STREAM,0);
//Tipo di indirizzo
temp.sin_family=AF_INET;
temp.sin_addr.s_addr=INADDR_ANY;
temp.sin_port=htons(Porta);
//Il socket deve essere non bloccante
errore=fcntl(sock,F_SETFL,O_NONBLOCK);
//Bind del socket
errore=bind(sock,(struct sockaddr*) &temp,sizeof(temp));
//Per esempio, facciamo accettare fino a 7 richieste di servizio
//contemporanee (che finiranno nella coda delle connessioni).
errore=listen(sock,7);
return sock;
}
void ChiudiSocket(int sock)
{
close(sock);
return;
}
int login(char* buffer)
{
//FORSE MI CONVIENE GESTIRE IL LOGIN COME UN THREAD....
/*Funzione di controllo del login:
*- Riceve la stringa 1:recvport:user:pass
*- Recupera la sotto stringhe user:pass per la ricerca nel file di testo e l'inserimento nella lista
*- Recupera la sottostringa recvport per la creazione del nodo UTENTE
* associato al tentativo di login (recvport viene utilizzato dal server per sapere dove smistare i messaggi)
*/
//Sottostringa recvport
printf("Buffer=%s\n",buffer);
int iniuser=0;
int inipass=0;
int flag=1;
char* recvport=(char*)calloc(32,sizeof(char));
int i,j;
for(i=2,j=0; i<strlen(buffer) && flag; i++) {
if(buffer[i]!=':'){
recvport[j]=buffer[i];
j++;
}
else{
//salva il punto in cui inizia la sottostringa successiva
iniuser=i;
flag=0;
}
}
recvport[j]='\0';
int recvp=atoi(recvport); //converte la stringa recvport in un intero!
printf("recvport: %d\n",recvp);
iniuser++;
//Sottostringa User
flag=1;
char* user=(char*)calloc(32,sizeof(char));
for(i=iniuser,j=0;i<strlen(buffer) && flag; i++) {
if(buffer[i]!=':'){
user[j]=buffer[i];
j++;
}
else{
//salva il punto in cui inizia la sottostringa successiva
inipass=i;
flag=0;
}
}
user[j]='\0';
printf("user: %s\n",user);
inipass++;
//Sottostringa Pass
flag=1;
char* pass=(char*)calloc(32,sizeof(char));
for(i=inipass,j=0;i<strlen(buffer) && flag; i++) {
if(buffer[i]!=':'){
pass[j]=buffer[i];
j++;
}
else{
//salva il punto in cui inizia la sottostringa successiva
flag=0;
}
}
pass[j]='\0';
printf("pass: %s\n",pass);
//Verifica se user:pass appartiene alla lista utenti
int finduser=ricerca3(user,strlen(user),pass,strlen(pass));
printf("Finduser=%d\n",finduser);
//Creazione del nodo in lista
if(finduser){
if(head!=NULL){head=insertHead(id,user,pass,0,0,recvp,head);}
else{head=newNode(id,user,pass,0,0,recvp);}
id++;
//invia messaggio al client dell'avvenuto login
printf("spedisce logincorrect\n");
onlysend("logincorrect",recvp);
free(user);
free(recvport);
free(pass);
return 1;
}
else
{
printf("spedisce incorrectlogin\n");
onlysend("incorrectlogin",recvp);
free(user);
free(recvport);
free(pass);
return 0;
}
}
//recupera i caratteri di comando dalla stringa es.(1:user:pass -> 1: tentativo di login)
char* stringcmd(char* buffer)
{
char* p=(char *)calloc(strlen(buffer), sizeof(char));//caratteri di comando
strncat(p,buffer,2);
return p;
}
//thread delle ricezioni
void* my_thread_listen(int DescrittoreSocketrecv)
{
char buffer[512];
int NuovoSocket;
int exitCond=0;
int Quanti;
int n=0;
//struct timeval tv;
fd_set readfds;
FD_ZERO(&readfds);
printf("Server: Attendo connessioni...\n");
while (!exitCond)
{
FD_SET(DescrittoreSocketrecv,&readfds);
//Test sul socket: accept non blocca, ma il ciclo while continua
//l'esecuzione fino all'arrivo di una connessione.
n=select(99999,&readfds,NULL,NULL,NULL);
if(n>0)
{
if ((NuovoSocket=accept(DescrittoreSocketrecv,0,0))!=-1)
{
//Lettura dei dati dal socket (messaggio ricevuto)
if ((Quanti=read(NuovoSocket,buffer,sizeof(buffer)))<0)
{
printf("Impossibile leggere il messaggio.\n");
ChiudiSocket(NuovoSocket);
}
else
{
//Aggiusto la lunghezza...
buffer[Quanti]=0;
//Elaborazione dati ricevuti
if (strcmp(buffer,"exit")==0)
exitCond=1;
else printf("Client: %s \n",buffer);
//traduci stringa del client per capire la direttiva
char* cmd=stringcmd(buffer);
if(strcmp(cmd,"1:")==0)
{
int flag=login(buffer);
printf("le FLag=%d\n",flag);
//Tentativo di login
printf("Tentativo di login\n");
}
}
//Chiusura del socket temporaneo
ChiudiSocket(NuovoSocket);
}
}
}
}
int CreaSocketsend(char* Destinazione, int Porta)
{
struct sockaddr_in temp;
struct hostent *h;
int sock;
int errore;
//Tipo di indirizzo
temp.sin_family=AF_INET;
temp.sin_port=htons(Porta);
h=gethostbyname(Destinazione);
if (h==0)
{
printf("Gethostbyname fallito\n");
exit(1);
}
bcopy(h->h_addr,&temp.sin_addr,h->h_length);
//Creazione socket.
sock=socket(AF_INET,SOCK_STREAM,0);
//Connessione del socket. Esaminare errore per compiere azioni
//opportune in caso di errore.
errore=connect(sock, (struct sockaddr*) &temp, sizeof(temp));
return sock;
}
void SpedisciMessaggio(int sock, char* Messaggio)
{
while(1){
//printf("Il tuo messaggio: %s\n",Messaggio);
//Si puo' notare il semplice utilizzo di write:
//write(socket, messaggio, lunghezza messaggio)
if (write(sock,Messaggio,strlen(Messaggio))<0)
{
//printf("Impossibile mandare il messaggio.\n");
//ChiudiSocket(sock);
//exit(1);
}else{
//printf("Messaggio spedito con successo.\n");
return;
}
}
}
void onlysend(char* msg,int port)
{
int DescrittoreSocketsend;
//msg=(char*)calloc(256,sizeof(char));
//printf("Inserisci Messagio da inviare\n");
//fgets(msg,256,stdin);
DescrittoreSocketsend=CreaSocketsend("127.0.0.1",port);
sleep(0.4);
SpedisciMessaggio(DescrittoreSocketsend,msg);
ChiudiSocket(DescrittoreSocketsend);
//mi metto in attesa dell'ascolto
}
int main()
{
pthread_t thlisten;
int retcode;
int DescrittoreSocketrecv;
//Creazione ThreadListen con socket non bloccanti
DescrittoreSocketrecv=CreaSocketrecv(1024);
retcode=pthread_create(&thlisten,NULL,my_thread_listen,DescrittoreSocketrecv);
pthread_join(thlisten,0);
//Chiusura del socket alla terminazione del programma
ChiudiSocket(DescrittoreSocketrecv);
printf("Client: Terminato.\n");
return 0;
}