Hi everyone! I'm a freshman in our forum. To the beginning, hope all of you have a nice day .
I'm having an assignment about UDP server client which exchange their bulletin to each other. Similar my code below i successfully ran completely with TCP. However, i can't figure out what is the reason why my code does not work . I'm totally clueless now.
Here is my code :
server:
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
client:
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define UDPPORT 5011
int main(int argc,char *argv[])
{
//tao 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;
strcpy(HEL.hello_id,"dientu-K53");
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;
struct bye {
char bye_id[11];
long int bye_detect;
} BYE;
strcpy(BYE.bye_id,"dientu-K53");
BYE.bye_detect=2;
//-------------ket thuc tao ban tin----------------------
int clientSocket=socket(PF_INET,SOCK_DGRAM,0);
struct hostent *he;
int check; //check return value of socket function
if(clientSocket==-1)
{
perror("error making socket\n");
exit(1);
}
struct sockaddr_in serveraddr, clientaddr;
int serveraddrlen=sizeof(serveraddr);
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(UDPPORT);
serveraddr.sin_addr.s_addr=INADDR_ANY;
he=gethostbyname(argv[1]);
//-----------------------Data processing begin ---------------------
printf("nhap email nguoi gui:\n"); int nsend;
gets(HEL.mail_user);
//verify the null
int dem=strlen(HEL.mail_user); //chieu dai
//HEL.mail_user[dem]='\0';
if(HEL.mail_user[dem]=='\0') printf("%d th la ki tu NULL\n",dem);
//calculate len:
HEL.hello_len=strlen(HEL.hello_id)+strlen(HEL.mail_user)+sizeof(HEL.hello_detect)+4;
//mail truoc:
nsend=sendto(clientSocket,HEL.mail_user,strlen(HEL.mail_user),0,(struct sockaddr *)&serveraddr,serveraddrlen);
if(nsend==-1)
{
printf("send email user error\n");
perror("SEND");
exit(0);
}
printf("hello_len= %ld \n",HEL.hello_len);
//send "hello" to server
nsend=sendto(clientSocket,HEL.hello_id,11,0,(struct sockaddr *)&serveraddr,serveraddrlen); //hello_id
if(nsend==-1)
{
printf("send hello_id error\n");
perror("SEND");
exit(0);
}
//PROBLEM HERE-them "&"truoc hello_len do truyen buffer
nsend=sendto(clientSocket,&HEL.hello_len,4,0,(struct sockaddr *)&serveraddr,serveraddrlen); //hello_len
if(nsend==-1)
{
printf("send hello_len error\n");
perror("SEND");
exit(0);
}
nsend=sendto(clientSocket,&HEL.hello_detect,4,0,(struct sockaddr *)&serveraddr,serveraddrlen); //hello_detect
if(nsend==-1)
{
printf("send hello_detect error\n");
perror("SEND");
exit(0);
}//PROBLEM HERE
printf("Waiting for server reply\n");
//goto Round_Check;
// ket thuc send hello
//*********************************************************
//nhan ACK & send BYE, dong socket
printf("nhan ACK, send BYE,close client's corresponding socket\n");
int nrecv;
nrecv=recvfrom(clientSocket,ACK.ack_id,11,0,(struct sockaddr *)&serveraddr,&serveraddrlen); //ack_id
if(nrecv==-1)
{
printf("error when receiving ack_id \n");
perror("RECEIVE");
exit(0);
}
//hien thi truong nhan dang ack_id cua client:
printf("truong nhan dang client= %s \n",ACK.ack_id);
nrecv=recvfrom(clientSocket,&ACK.ack_len,4,0,(struct sockaddr *)&serveraddr,&serveraddrlen); //ack_len
if(nrecv==-1)
{
printf("error when receiving ack_len \n");
perror("RECEIVE");
exit(0);
}
nrecv=recvfrom(clientSocket,&ACK.ack_detect,4,0,(struct sockaddr *)&serveraddr,&serveraddrlen); //ack_detect
if(nrecv==-1)
{
printf("error when receiving ack_detect \n");
perror("RECEIVE");
exit(0);
}
nrecv=recvfrom(clientSocket,ACK.client_mail,sizeof(HEL.mail_user),0,(struct sockaddr *)&serveraddr,&serveraddrlen); //ack_mail
if(nrecv==-1)
{
printf("error when receiving client_mail \n");
perror("RECEIVE");
exit(0);
}
nrecv=recvfrom(clientSocket,ACK.ack_state,20,0,(struct sockaddr *)&serveraddr,&serveraddrlen); //ack_state
if(nrecv==-1)
{
printf("error when receiving ack_state \n");
perror("RECEIVE");
exit(0);
}
//hien thi truong trang thai ack_state:
//khong can them ki tu NULL do luc dau send mail da co
printf("luu tru email user tai server: %s \n",ACK.ack_state);
//goto Round_Check;
//**********************************Round2********************************
//send "BYE" back to server
nsend=sendto(clientSocket,BYE.bye_id,11,0,(struct sockaddr *)&serveraddr,serveraddrlen); //bye_id
if(nsend==-1)
{
printf("error occurrs when sending bye_id\n");
perror("SEND");
exit(0);
}
nsend=sendto(clientSocket,&BYE.bye_detect,4,0,(struct sockaddr *)&serveraddr,serveraddrlen); //bye_detect
if(nsend==-1)
{
printf("error occurrs when sending bye_detect\n");
perror("SEND");
exit(0);
}
printf("send BYE to server successfully, gonna close socket\n");
//-----------------------Data processing end----------------------
close(clientSocket);
exit(0);
} //------end of main---------
Probably there is something goes wrong with my select() function. I've tried to fix but they are all helpless.
Looking forward to your advices