Article 4Y82J Why does my server cannot respond to multiple clients simultaneously even after using fork function?

Why does my server cannot respond to multiple clients simultaneously even after using fork function?

by
intstudent123
from LinuxQuestions.org on (#4Y82J)
Hi, I'm a newbie here. For a school assignment, my group has to create a simple email system which requires two servers; the SMTP and POP. I am assigned to create the SMTP server so that the server can respond to multiple clients simultaneously. I use the fork function because it is easier to be explained in later presentations.

Below are the server and client program.

smtp.c

Code:#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <sys/wait.h>

#define ERR -1
#define MAX 64
#define SERVER_IP "127.0.0.1" //local loopback
#define SMTP 1900
#define POP 1901

int main(){
int sock, cli, k;
unsigned int len;
int sent;
struct sockaddr_in server, client;
char buff[MAX], msg[MAX], to[MAX], Cc[MAX], txt[]="rec.txt", file_dir[MAX];
FILE *fp;
pid_t child_pid;

system("clear");
// create socket
if((sock = socket(AF_INET, SOCK_STREAM, 0)) == ERR){
perror("socket: ");
exit(-1);
}

server.sin_family = AF_INET;
server.sin_port = htons(SMTP);
server.sin_addr.s_addr = INADDR_ANY;

// bind
len = sizeof(struct sockaddr_in);
if(bind(sock, (struct sockaddr *)&server, sizeof(server)) == ERR){
perror("bind");
exit(-1);
}

// listen
if((listen(sock, 10)) == ERR){
perror("listen");
exit(-1);
}

while(1){
memset(buff, 0, sizeof(buff));
memset(msg, 0, sizeof(msg));
memset(to, 0, sizeof(to));
memset(Cc, 0, sizeof(Cc));

printf("(SMTP) Waiting for connection\n");
if((cli = accept(sock, (struct sockaddr *)&client, &len)) == ERR){
perror("accept");
exit(-1);
}

// create child process
child_pid = fork();

if (child_pid < 0) {
perror("fork");
exit(-1);
}
// child
else if (child_pid == 0) {
close(sock); // close child copy
// receive from client
recv(cli, to, sizeof(msg), 0);
printf("Connection request to %s\n",to);

for(k=0;;k++){
sprintf(file_dir,"%s/mail%d.txt", to, k+1);
if ((fp = fopen(file_dir, "r")) == NULL) break;
}
fp = fopen(file_dir, "w");
while(strcmp(msg,".") != 0){
recv(cli, msg, sizeof(msg),0);
if(strcmp(msg,".") == 0){
strcpy(buff, "1");
}
else{
strcpy(buff, "0");
}
fprintf(fp, "%s\n", msg);
send(cli, buff, sizeof(buff), 0);
}

fclose(fp);
// Cc
// init buff and msg
memset(buff, 0, sizeof(buff));
memset(msg, 0, sizeof(msg));
// process
recv(cli, Cc, sizeof(msg), 0);
printf("Connection request to %s\n\n",Cc);

for(k=0;;k++){
sprintf(file_dir,"%s/mail%d.txt", Cc, k+1);
if ((fp = fopen(file_dir, "r")) == NULL) break;
}
fp = fopen(file_dir, "w");
while(strcmp(msg,".") != 0){
recv(cli, msg, sizeof(msg),0);
if(strcmp(msg,".") == 0){
strcpy(buff, "1");
}
else{
strcpy(buff, "0");
}
fprintf(fp, "%s\n", msg);
send(cli, buff, sizeof(buff), 0);
}

fclose(fp);
close(cli);
exit(0); // child exits here
}
// parent
else{
close(cli); // close parent copy
waitpid(child_pid, NULL, 0); // waits for child to exit
}
}
close(sock);
return 0;
}client.c

Code:#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>

#define FALSE 0
#define TRUE 1
#define MAX 64
#define SERVER_IP "192.168.0.102"
#define SMTP 1900
#define POP 1901

char from[MAX];
int debug=FALSE; //TRUE or FALSE

int smtp();
int fgets_or(char buff[],int size);
int fprintf_or(FILE *fp,char format[],char buff[]);
int get_info(char ret[],char file[],int line);
int cut(char ret[],char data[],const char *token,int point);
int wait_ent(void);

int main(void){
// variables
typedef struct list{
int id;
char *mode;
} List;

int i,val;
char buff[MAX];
const List menu[]={{1,"Send"},{0,"End"}};

system("clear");
printf("Input email address\n > ");
fgets_or(from,MAX-1);
while(1){
system("clear");
printf("Hello %s\n\nMenu\n",from);
for(i=0;i<(int)(sizeof(menu)/sizeof(menu[0]));i++) printf("%d : %s ",menu[i].id,menu[i].mode);
printf("\n > ");
fgets(buff, MAX, stdin);
val=atoi(buff);
switch(val){
case 1:
smtp();
break;
case 0:
printf("\nGoodbye %s\n",from);
return 0;
default:
fprintf(stderr,"\nInvalid value is assigned\n");
wait_ent();
}
}
return 0;
}

int smtp(){
// variables
int sd;
char buff[MAX],msg[MAX],file[]="mail0.txt";
FILE *fp;
time_t t;
struct sockaddr_in addr;

system("clear");
// create mail
if((fp = fopen(file,"w")) == NULL){
fprintf(stderr,"Failed to open file\n");
wait_ent();
return -1;
}
fprintf_or(fp,"From;%s\n",from);
printf("To\n > ");
fgets_or(buff,MAX-1);
fprintf_or(fp,"To;%s\n",buff);
printf("Cc\n (If none, enter 0)> ");
fgets_or(buff,MAX-1);
fprintf_or(fp,"Cc;%s\n",buff);
t=time(NULL);
strftime(buff, sizeof(buff), "%Y/%m/%d %H:%M:%S", localtime(&t));
fprintf_or(fp,"Date;%s\n",buff);
printf("Subject\n > ");
fgets(buff, MAX-1, stdin);
buff[strlen(buff) - 1] = '\0';
fprintf_or(fp,"Subject;%s\n",buff);
memset(buff,0,sizeof(buff));
printf("Body(Ends at'.')\n");
while(strcmp(buff,".") != 0){
printf(" > ");
fgets(buff, MAX-1, stdin);
buff[strlen(buff) - 1] = '\0';
fprintf_or(fp,"%s\n",buff);
}
fclose(fp);
// buffer initialization
memset(buff,0,sizeof(buff));
memset(msg,0,sizeof(buff));
// create socket
if((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
wait_ent();
return -1;
}
// sender's address and port number
addr.sin_family = AF_INET;
addr.sin_port = htons(SMTP);
addr.sin_addr.s_addr = inet_addr(SERVER_IP);
// server connection
if(connect(sd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < 0){
perror("connect");
wait_ent();
return -1;
}
// sending process
if(debug==TRUE) printf("\nConnect to server\n");
// user information
get_info(buff,file,2);
cut(buff,buff,";@",2);
send(sd, buff, sizeof(buff),0);
// body
if((fp = fopen(file,"r")) == NULL){
fprintf(stderr,"Failed to open file\n");
close(sd);
wait_ent();
return -1;
}
while (strcmp(msg,"1") != 0) {
fgets(buff, MAX-1, fp);
buff[strlen(buff) - 1] = '\0';
send(sd, buff, sizeof(buff),0);
recv(sd, msg, sizeof(msg),0);
}
fclose(fp);
if(debug==TRUE) printf("\nDisconnect from server\n");
// Cc
// buffer initialization
memset(buff,0,sizeof(buff));
memset(msg,0,sizeof(buff));
// user information
get_info(buff,file,3);
cut(buff,buff,";@",2);
send(sd, buff, sizeof(buff),0);
// body
if((fp = fopen(file,"r")) == NULL){
fprintf(stderr,"Failed to open file\n");
close(sd);
wait_ent();
return -1;
}
while (strcmp(msg,"1") != 0) {
fgets(buff, MAX-1, fp);
buff[strlen(buff) - 1] = '\0';
send(sd, buff, sizeof(buff),0);
recv(sd, msg, sizeof(msg),0);
}
fclose(fp);
close(sd);
if(debug==TRUE) printf("\nDisconnect from server\n");
remove(file);
printf("\nSent\n");
wait_ent();
return 0;
}
//do not allow space
int fgets_or(char buff[],int size){
do {
if (fgets(buff, size, stdin) == NULL){
buff='\0';
return -1;
}
buff[strlen(buff) - 1] = '\0';
} while (strcmp(buff, "\0") == 0);
return 0;
}
// error handling with fprintf
int fprintf_or(FILE *fp,char format[],char buff[]){
if(fprintf(fp,format,buff) < 0){
fprintf(stderr,"afaaafa(R)aeae3/41/4aaaae-a-a3/4a-a\n");
fclose(fp);
wait_ent();
return -1;
}
return 0;
}
//Function to store line of file in ret
int get_info(char ret[],char file[],int line){
int i;
char buff[MAX][MAX];
FILE *fp;

if((fp = fopen(file,"r")) == NULL){
fprintf(stderr,"afaaafa(R)aaf1/4af-af^3aaae-a-a3/4a-a\n");
wait_ent();
return -1;
}
for(i=0;fgets(buff[i], sizeof(buff[i]), fp) != NULL;i++);
fclose(fp);
cut(buff[line-1],buff[line-1],"\n",1);
strcpy(ret,buff[line-1]);
//printf("%s\n",ret); debug
return 0;
}
//Function to store the point element in ret when character string data is separated by token
int cut(char ret[],char data[],const char *token,int point){
int len=1,i=0;
char *tp,buff[MAX],*argv[MAX];

strcpy(buff,data);
tp=strtok(buff,token);
argv[i]=tp;
for(i=1;i<MAX && tp!=NULL;i++) {
tp=strtok(NULL,token);
if(tp!=NULL){
argv[i]=tp;
len++;
}
}
if(point-1<len) strcpy(ret,argv[point-1]);
else strcpy(ret,"");
//printf("%s\n",ret); debug
return 0;
}
// wait until Enter is pressed
int wait_ent(void){
char buff[MAX];

printf("\nPress Enter to disconnect");
fgets(buff, sizeof(buff), stdin);
return 0;
}Note: Must create directory folders for the clients. For example, A, B, and C. When entering the email address, simply input A@. At client.c, the SERVER_IP must be changed according to the IP address of the computer used for the server execution.

To test it, I open two terminals, for example, A and B. Supposedly, if I try to send emails from A and B at the same time, the server will properly display the connection requested from the clients and the emails are written will be transferred in the mail receiver folders. However, it seems that it cannot connect two clients simultaneously. This makes me confused and I don't know where to change anymore in the coding.

It would be great if there's anyone that can help me solving this. Thank you in advance.latest?d=yIl2AUoC8zA latest?i=1N7CE5T3Hds:VHHpfuvxqAE:F7zBnMy latest?i=1N7CE5T3Hds:VHHpfuvxqAE:V_sGLiP latest?d=qj6IDK7rITs latest?i=1N7CE5T3Hds:VHHpfuvxqAE:gIN9vFw1N7CE5T3Hds
External Content
Source RSS or Atom Feed
Feed Location https://feeds.feedburner.com/linuxquestions/latest
Feed Title LinuxQuestions.org
Feed Link https://www.linuxquestions.org/questions/
Reply 0 comments