Code:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc,char* argv[])
{
//---------------- tao cac struct ban tin----------
struct hello {
char hello_id[11];//10 ky tu dientu-k53 + 1 ki tu ket thuc
long int hello_len; //32bit
long int hello_detect;
char mail_user[50]; //mail user from client
} HEL;
HEL.hello_detect=0;
struct acknowledgement {
char ack_id[11];
long int ack_len;
long int ack_detect;
char client_mail[50]; //tra ve mail user cho client
char ack_state[20]; //trang thai "success" or "failed"
} ACK;
strcpy(ACK.ack_id,"dientu-K53");
ACK.ack_detect=1;
//char ack_state[]; //vua thay doi
struct bye {
char bye_id[11];
long int bye_detect;
} BYE;
strcpy(BYE.bye_id,"dientu-K53");
BYE.bye_detect=2;
int dem=0;
//----------ket thuc tao ban tin -----------------
int serverSocket;
serverSocket=socket(PF_INET,SOCK_DGRAM,0);
if(serverSocket==-1)
{
perror("UDP server socket !!! \n");
close(serverSocket);
exit(1);
}
int i=1; //option for enabling reuse option below
int check;
/*check=setsockopt(serverSocket,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(int));
if(check=-1)
{
perror("failed to set reuse\n");
} */
//---------loading socket address structure------------
struct sockaddr_in serverAddress;
//struct sockaddr_in clientAddress;
serverAddress.sin_family=AF_INET;
serverAddress.sin_port=htons(5011);
serverAddress.sin_addr.s_addr=INADDR_ANY;
//socklen_t len=sizeof (struct sockaddr_in);
//-------------------define length of clientaddr , serveraddr--------------------
//int clientaddrlen=sizeof(clientAddress);
int serveraddrlen=sizeof(serverAddress);
check=bind(serverSocket,(struct sockaddr *)&serverAddress,serveraddrlen);
if(bind==-1)
{
perror("failed to bind socket address structure\n");
close(serverSocket);
exit(0);
} //gia tri tra ve cua bind trong UDP connectionless la con tro
else {//--------------DATA handling begin ----------------------
printf("chuan bi xu ly \n");
//------------------------Declare prototypes-------------------------
//struct sockaddr_in clientAddress;
//len=sizeof(struct sockaddr_in);
fd_set readfds; //check sockets ready for reading
fd_set masterfds; //luu thay doi cua readfds
FD_ZERO(&readfds);
FD_ZERO(&masterfds);
FD_SET(serverSocket,&masterfds); //add udp serverSocket vao array masterfds
int max_fd=serverSocket; //=3
struct timeval timeout; //timeout cho select()
timeout.tv_sec=90;
timeout.tv_usec=0;
int n_select;
int close_fd=0; //khai bao kiem tra fd state
do { //-----endless loop---------------
memcpy(&readfds,&masterfds,sizeof(masterfds)); //load masterfds to readfds
printf("chuan bi select \n");
n_select=select(max_fd+1,&readfds,NULL,NULL,NULL);
printf("da thuc hien ham select \n");
if (n_select < 0)
{
perror("SELECT");
exit(0);
}
else
if (n_select == 0)
{
printf("Time out\n");
}
else
{
i=serverSocket;
// for (i = 0; i <= max_fd;i++) //duyet cac file descriptors
//{
if (FD_ISSET(i,&readfds))//neu co file descriptor"ready to read"
{
//int close_fd = 0; //kiem tra socket co nen duoc dong sau khi xu ly hay ko?
struct sockaddr_in clientAddress;
int clientaddrlen=sizeof(clientAddress);
//gan i =serverSocket
//-----------------------Data processing---------------------------------------
printf("receive HELLO+send ACK bulletin\n");
printf("Receive data in socket %d\n",i);
int nrecv ;
//nhan mail tu remote client
char mail_temp[100][50]; //danh sach tam
dem++; //thao tac tren mail list dau tien
nrecv=recvfrom(i,mail_temp[dem],50,0,(struct sockaddr*)&clientAddress,&clientaddrlen); //hello_mail
if(nrecv==-1)
{
printf("In socket-received mail %d\n",i);
perror("RECEIVE");
close_fd=1;
}// end if nrecv_mail
//hien thi chuoi
printf("mail user tu client gui la: %s\n",mail_temp[dem]);
//-------------------------------------------------------
nrecv= recvfrom(i,HEL.hello_id,11,0,(struct sockaddr*)&clientAddress,&clientaddrlen); //PROBLEM HERE-chua gan default cho hello_id o client
if (nrecv == -1)
{
printf("In socket-receive ID %d\n",i);
perror("RECEIVE");
close_fd = 1; //co loi nao close_fd=1 de dong socket
}
// else
// {
printf("Hello_id received=%s.\n",HEL.hello_id);
if(strcmp(HEL.hello_id,"dientu-K53")==0) //hello_id :dung-> tra ve 0
{
printf("ban tin hop le \n");
goto moveon;
}
else
{
printf("ban tin khong hop le\n");
exit(0);
}
//nhan gia tri hello_len
moveon: nrecv=recvfrom(i,&HEL.hello_len,4,0,(struct sockaddr*)&clientAddress,&clientaddrlen);
if(nrecv==-1)
{
printf("In socket-received length: %d \n",i);
perror("RECEIVE");
//close_fd=1;
}//end if nrecv_len
//nhan gia tri hello_detect
nrecv=recvfrom(i,&HEL.hello_detect,4,0,(struct sockaddr*)&clientAddress,&clientaddrlen);
if(nrecv==-1)
{
printf("In socket-received detect: %d \n",i);
perror("RECEIVE");
close_fd=1; //dong socket
}
//Save email user vao mang 2 chieu
char list_mail [100][50];
//mang 1 chieu 100 phan tu, moi phan tu 50 ki tu-> giong danh sach
// int count=0;
In_mail: strcpy(list_mail[dem],mail_temp[dem]);
//cong luon
printf("mail vua update vao list la: %s \n",list_mail[dem]);
int j=1;
printf("------------------Hien thi danh sach email:---------------\n");
for(j=1;j<=dem;j++)
{
printf(" mail thu %d : %s \n ",j,list_mail[j]);
}
printf("-------------------End my list----------------------");
//gan gia tri cho truong trang thai ACK.ack_state
if(strcmp(list_mail[dem],mail_temp[dem])==0) //dung->return 0
{
printf("luu email thanh cong \n");
strcpy(ACK.ack_state,"success");
printf("ack vua gan la %s \n",ACK.ack_state);
}
else
{
printf("luu email that bai \n");
strcpy(ACK.ack_state,"failed");
}
//ACK length calculation
//HEL.hello_len=strlen(HEL.hello_id)+strlen(HEL.mail_user)+sizeof(HEL.hello_detect);
ACK.ack_len=strlen(ACK.ack_id)+sizeof(ACK.ack_detect)+strlen(ACK.client_mail)+strlen(ACK.ack_state)+4;
//feedback lai client ban tin ack:
int nsent;
nsent=sendto(i,ACK.ack_id,11,0,(struct sockaddr*)&clientAddress,clientaddrlen); //ack_id
if(nsent==-1)
{ printf("In socket-error when sending ack ID %d\n",i);
perror("SEND");
close_fd = 1;
}
nsent=sendto(i,&ACK.ack_len,4,0,(struct sockaddr*)&clientAddress,clientaddrlen); //ack_len
if(nsent==-1)
{ printf("In socket-error when sending ack len %d\n",i);
perror("SEND");
close_fd = 1;
}
nsent=sendto(i,&ACK.ack_detect,4,0,(struct sockaddr*)&clientAddress,clientaddrlen); //ack_detect
if(nsent==-1)
{ printf("In socket-error when sending ack detect %d\n",i);
perror("SEND");
close_fd = 1;
}
strcpy(ACK.client_mail,mail_temp[dem]); //ack_mail -< error
nsent=sendto(i,ACK.client_mail,50,0,(struct sockaddr*)&clientAddress,clientaddrlen);
if(nsent==-1)
{ printf("In socket-error when sending back CLIENT MAIL %d\n",i);
perror("SEND");
close_fd = 1;
}
printf("state chuan bi gui di la : %s \n",ACK.ack_state);
nsent=sendto(i,ACK.ack_state,20,0,(struct sockaddr*)&clientAddress,clientaddrlen); //ack_state
if(nsent==-1)
{ printf("In socket-error when sending ack_state %d\n",i);
perror("SEND");
close_fd = 1;
}
printf("state vua gui di la : %s \n",ACK.ack_state);
printf("successfully sent ACK bulletin to client\n");
//goto Round_Check;
//int nsent = send(i,message2,strlen(message2),0);
//end feedback
/* else
{
close_fd = 1;
}*/
printf("receive BYE bulletin \n"); //PROBLEM HERE?
nrecv=recvfrom(i,BYE.bye_id,11,0,(struct sockaddr*)&clientAddress,&clientaddrlen); //bye_id
if(nrecv==-1)
{
printf("received bye_id bulletin failed\n");
perror("RECEIVE");
exit(0);
}
nrecv=recvfrom(i,&BYE.bye_detect,4,0,(struct sockaddr*)&clientAddress,&clientaddrlen); //bye_detect
if(nrecv==-1)
{
printf("received bye_id bulletin failed\n");
perror("RECEIVE");
exit(0);
}
close_fd=1;
printf("remote client closed its socket\n");
goto close_socket; //thoat khoi checking FD_ISSET
//-----------------------End of data processing--------------------------------
}//end if of FD_ISSET
//}//end for
}//end of else
}//end do while
while(1);
}// ------------------end esle of DATA handling--------------------
//close(close_fd);
close_socket: close(serverSocket);
exit(0);
}//end main