This program, on the server side, asks the user for an array size, array elements and an integer value to be searched in the array. If found it prints a message such as "The value 87 occurs at index position 4" and sends it back to client. I have managed to come up with the following code for server and client. However, how do I send the result of the search such as "The value 87 occurs at index position 4" back to server from client?
Client Code:
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#define MAX_SIZE 10 //maximum array size
int main (void)
{
int fda; // to write to server
int fdb; // to read response from server
struct{
int size;
int i;
int arr[MAX_SIZE];
} input;
if((fda=open("FIFO_to_server", O_WRONLY))<0)
printf("cant open fifo to write");
printf("Client: Please enter size of the array: ");
scanf("%d", &input.size);
printf("Enter the elements of the array: ");
for(i=0; i<size; i++)
{
scanf(%d", &arr[i]);
}
write(fda, &input, sizeof(input));
close(fda);
printf("\nClient: Got the array sent, now waiting for response ");
if((fdb=open("FIFO_to_client", O_RDONLY))<0)
printf("cant open fifo to read");
close(fdb);
printf ("\nall done!\n");
}
Server Code
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/types.h>
int main (void)
{
int fda; // to read from client
int fdb; // to write
int i;
int toSearch;
int found;
int finish;
/* Create the fifos and open them */
if ((mkfifo("FIFO_to_server",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO_to_server");
exit(-1);
}
if ((mkfifo("FIFO_to_client",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO_to_client");
exit(-1);
}
if((fda=open("FIFO_to_server", O_RDONLY))<0)
printf("cant open fifo to write");
if((fdb=open("FIFO_to_client", O_WRONLY))<0)
printf("cant open file to read");
finish=read(fda, &input, sizeof(input));
printf("Server: just got the array: %d", arr);
printf("\Enter the integer to be searched in the array: ");
found = 0;
for(i=0; i<size; i++)
{
if(arr[i] == toSearch)
{
found = 1;
break;
}
}
if(found == 1)
{
printf("\n%d is found at position %d", toSearch, i + 1);
}
else
{
printf("\n%d is not found in the array", toSearch);
}
return 0;
close(fdb);
unlink("FIFO_to_client");
close(fda);
unlink("FIFO_to_server");
}
Related
I have 2 programs.
One is server one is client. The Client sending string to the server, the server is swapping the string and return to the client.
the problems I have is when I pressing ctr+c the program(client) closed.(I'm using threads because I have been asking for.)
So how can I keep the program unclosed after ctr+c?
when clicking enter this is the right result and waiting for the server.
when entering ctl+c the program closed and cannot running server.c
The client.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#define MAX_BUF 1024
// client
int main()
{
int fd;
char *myfifo = "myfifo";
char str[MAX_BUF];
printf("Input string: ");
fgets(str, MAX_BUF, stdin);
str[strlen(str) - 1] = '\0';
if (mkfifo("myfifo", 0777) == -1)
{
if (errno != EEXIST)
{
printf("Could not create fifo file\n");
return 1;
}
}
/* create the FIFO (named pipe) */
fd = open(myfifo, O_WRONLY);
if (fd == -1)
return 2;
if (write(fd, str, MAX_BUF) == -1)
return 3;
close(fd);
fd = open(myfifo, O_RDONLY);
read(fd, str, MAX_BUF);
printf("%s\n", str);
/* remove the FIFO */
unlink(myfifo);
return 0;
}
The server
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#define MAX_BUF 1024
// server
// creatring struct for saving data
typedef struct thread_data
{
char str[MAX_BUF];
int result;
} thread_data;
// the
void *routine(void *arg)
{
int fd[2];
char *myfifo = "myfifo";
thread_data *tdata = (thread_data *)arg;
if (!(strcmp(tdata->str, "exit")))
tdata->result = 1; // is exit
else
tdata->result = 0; // not exit
if (tdata->result == 1)
{
fd[1] = open(myfifo, O_WRONLY);
write(fd[1], "Done", sizeof(MAX_BUF));
close(fd[1]);
}
else
{
char string[MAX_BUF] = {0};
char c = 0;
int length = 0, i = 0;
length = strlen(tdata->str);
printf("\nBefore Swap : %s\n", tdata->str);
for (i = 0; i < length / 2; i++)
{
c = tdata->str[i];
tdata->str[i] = tdata->str[length - 1 - i];
tdata->str[length - 1 - i] = c;
}
printf("\nAfter Swap String : %s\n", tdata->str);
fd[1] = open(myfifo, O_WRONLY);
write(fd[1], tdata->str, sizeof(MAX_BUF));
close(fd[1]);
}
pthread_exit(NULL);
}
int Calculation()
{
int fd[2];
// fd[0] read
// fd[1] write
char *myfifo = "myfifo";
char buf[MAX_BUF];
/* open, read, and display the message from the FIFO */
fd[0] = open(myfifo, O_RDONLY);
if(fd[0]==-1)
return 4;
if(read(fd[0], buf, MAX_BUF)==-1)
return 5;
close(fd[0]);
// res
int result;
thread_data tdata;
strcpy(tdata.str, buf);
pthread_t t1;
if (pthread_create(&t1, NULL, &routine, (void *)&tdata) != 0)
{
return 1;
}
if (pthread_join(t1, NULL) != 0)
{
return 2;
}
}
int main()
{
int res = Calculation();
return res;
}
To avoid closing a program you should capture and
manage the signal sent by CTRL + C, that is SIGINT, I have modified the code so that it captures the signal CTRL + C
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <time.h>
#define MAX_BUF 1024
// client
int main()
{
signal(SIGINT,SIG_IGN); // Register signal handler for ignoring the signal
int fd;
char *myfifo = "myfifo";
char str[MAX_BUF];
printf("Input string: ");
fgets(str, MAX_BUF, stdin);
str[strlen(str) - 1] = '\0';
if (mkfifo("myfifo", 0777) == -1)
{
if (errno != EEXIST)
{
printf("Could not create fifo file\n");
return 1;
}
}
/* create the FIFO (named pipe) */
fd = open(myfifo, O_WRONLY);
if (fd == -1)
return 2;
if (write(fd, str, MAX_BUF) == -1)
return 3;
close(fd);
fd = open(myfifo, O_RDONLY);
read(fd, str, MAX_BUF);
printf("%s\n", str);
/* remove the FIFO */
unlink(myfifo);
return 0;
}
I have to create a client and server, where the client will send a character and an integer (using structs) and then my client will iterate the letter by n (integer) times and will send it back to the client.
For instance: a and 4 are sent from the client, server will manipulate and send a string of 4 a's (aaaa) back to the client.
I know I am really close to get the code but once I send my char and int, I get a "segmentation fault (core dumped) error". I have done my research and the error shows up due to a missing cast, memory being accessed where is not supposed to access, or that a pointer might be null.
The code is as follow:
Client:
// ClientTest.c
// opens fifo1 for writing and fifo2 for reading
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
struct problem {
char letter[1];
int number[1];
};
main (void)
{
struct problem x=0; //Initializing structure to null
int fda; // to write to character server
int fdb; // to read response from character server
int i; // for the iteration
printf("Client: Please enter a character: ");
scanf("%c", &x.letter[0]);
printf("Client: Please enter an integer: ");
scanf("%d", &x.number[0]);
memset(&x.letter, 0, 1);
memset(&x.number, 0, 1);
if((fda=open("FIFO1", O_WRONLY))<0)//opening and validating fifos
printf("cant open fifo to write");
if((fdb=open("FIFO2", O_RDONLY))<0)
printf("cant open fifo to read");
write(fda, x.number, 1);
printf("\nClient: Got the integer sent, now waiting for response ");
//sleep(0.250);
write(fda, x.letter, 1);
printf("\nClient: Got the character sent, now waiting for response ");
char outletter[7];
read(fdb, outletter, 7);
printf("\nClient: received characters from server %c", outletter);
close(fda);
close(fdb);
printf ("\nall done!\n");
}
server
// ServerTest.c
// makes 2 fifos named fifo1 and fifo2
// opens fifo1 for reading and fifo2 for writing
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
struct problem {
char letter[1]; // struct to store the character
int number [1]; // struct to store the integer
};
main (void)
{
struct problem x;
int fda; // to read from client char
int fdb; // to write to client char
int finish; // lets me know that client is done
int i; // because C needs this defined as int
int p;
char outletter[7];
memset(&x.letter, 0, 7);
memset(&x.number, 0, 1);
/* Create the fifos and open them */
if ((mkfifo("FIFO1",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO1");
exit(-1);
}
if ((mkfifo("FIFO2",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO2");
exit(-1);
}
if((fda=open("FIFO1", O_RDONLY))<0)
printf("cant open fifo to write");
if((fdb=open("FIFO2", O_WRONLY))<0)
printf("cant open fifo to read");
read(fda, x.letter, 1); //read the character
read(fda, x.number, 1); //read the integer
printf("\nServer: just got character: , %c", x.letter[0]);
printf("\nServer: just got integer: , %d", x.number[0]);
p=x.number[0]-'0';
for( i = 0; i<=p; i++) // iteration to create the character's string
outletter[p] = x.letter[0];
printf("iteration: %d and character: %c\n", i, outletter[0]); // validating the character and integer received
printf("\nServer: outchar is, %s", outletter); // this shows the character to be sent back to client
write(fdb, outletter, p);
printf("\nServer: Got the characters sent: %s", outletter ); // this sends the letter back to client
if(finish == 1)
printf("\nServer: This says I am ready to close ");
close(fda);
close(fdb);
unlink("FIFO1");
unlink("FIFO2");
}
There are many problems with your code, I've made it running but you can still improve it.
Client:
// ClientTest.c
// opens fifo1 for writing and fifo2 for reading
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
struct problem {
char letter[1];
int number[1];
};
main (void)
{
struct problem x;
int fda; // to write to character server
int fdb; // to read response from character server
int i; // for the iteration
memset(&x, 0, sizeof(struct problem)) ;
printf("Client: Please enter a character: ");
scanf("%c", x.letter);
printf("Client: Please enter an integer: ");
scanf("%d", x.number);
// removed or else the letter and number would be reverted to zero
// memset(&x.letter, 0, sizeof(char));
// memset(&x.number, 0, sizeof(int));
if((fda=open("FIFO1", O_WRONLY))<0)//opening and validating fifos
printf("cant open fifo to write");
if((fdb=open("FIFO2", O_RDONLY))<0)
printf("cant open fifo to read");
write(fda, x.letter, sizeof(char));
printf("\nClient: Got the character sent, now waiting for response ");
write(fda, x.number, sizeof(int));
printf("\nClient: Got the integer sent, now waiting for response ");
//sleep(0.250);
char outletter[7];
read(fdb, outletter, 7);
printf("\nClient: received characters from server:") ;
printf("%s\n", outletter);
close(fda);
close(fdb);
printf ("\nall done!\n");
}
Server:
// ServerTest.c
// makes 2 fifos named fifo1 and fifo2
// opens fifo1 for reading and fifo2 for writing
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
struct problem {
char letter[1]; // struct to store the character
int number[1]; // struct to store the integer
};
main (void)
{
struct problem x;
int fda; // to read from client char
int fdb; // to write to client char
int finish; // lets me know that client is done
int i; // because C needs this defined as int
int p;
char outletter[7];
memset(x.letter, 0, sizeof(char));
memset(x.number, 0, sizeof(int));
/* Create the fifos and open them */
if ((mkfifo("FIFO1",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO1");
exit(-1);
}
if ((mkfifo("FIFO2",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO2");
exit(-1);
}
if((fda=open("FIFO1", O_RDONLY))<0)
printf("cant open fifo to write");
if((fdb=open("FIFO2", O_WRONLY))<0)
printf("cant open fifo to read");
read(fda, x.letter, sizeof(char)); //read the character
read(fda, x.number, sizeof(int)); //read the integer
printf("\nServer: just got character: , %c", x.letter[0]);
printf("\nServer: just got integer: , %d", x.number[0]);
p=x.number[0];
if (p > 6) p = 6; // Cannot write more than 6 characters in outletter
for( i = 0; i<=p; i++) { // iteration to create the character's string
outletter[i] = x.letter[0];
printf("iteration: %d and character: %c\n", i, outletter[i]); // validating the character and integer received
}
outletter[p] = '\0'; // the string must finish with '\0'
printf("\nServer: outchar is, %s", outletter); // this shows the character to be sent back to client
write(fdb, outletter, p);
printf("\nServer: Got the characters sent: %s", outletter ); // this sends the letter back to client
if(finish == 1)
printf("\nServer: This says I am ready to close ");
close(fda);
close(fdb);
unlink("FIFO1");
unlink("FIFO2");
}
I'm trying to write and read from a named fifo with some methods... Apparently when I run it gets stuck on write_fifo(0) for no reason... So my question is am I using named fifo in the right way? Or does the unlink method mess with my program? When and where can I unlink a named fifo.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
void write_fifo(int s)
{
printf("write_fifo");
int writing, n;
writing = open("myFIFO",O_WRONLY);
n = write(writing, &s, sizeof(s));
printf("write: %i byte.\n", n);
close(writing);
unlink("myFIFO");
}
int read_fifo()
{
printf("read_fifo");
int reading, n, s;
reading = open("myFIFO", O_RDONLY);
n = read(reading , &s, sizeof(s));
printf("read: %i byte: %d\n", n, s);
close(reading);
unlink("myFIFO");
return s;
}
int main()
{
printf("beginning");
printf("removing myFIFO");
if (mkfifo("myFIFO", FILE_MODE) == -1)
{
perror("myFIFO");
exit(1);
}
write_fifo(0);
printf("\n\n\n\n\n\n\nReading %d",read_fifo());
return 0;
}
I tried reading from the file "hello.txt" but it doesn't enter the while loop at all. The read function returns 0 on EOF and -1 on error. I'm trying to search for the word in w if it exists in the file or not. I'm reading characters from the file and comparing them to w[].
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
int main()
{
int fd;
char c;
int i=0;
int bytesread;
int flag=1;
char w[]={'h','e','l','l','o'};
if((fd=open("hello.txt",O_RDONLY,0))!=-1){ //if 1
bytesread = read(fd,&c,0);
if(bytesread!=-1){ //if 2
while(bytesread!=0)
{ //while
if(c==w[i])
{ //if 3
i++;
flag=0;
} //end of f3
else if(flag==0&&i!=0)
{ // else 3
i=0;
flag=1;
} // end of else 3
bytesread = read(fd,&c,0);
} //end of while
}else //end of if 2
printf("couldn't read file.\n");
}else //end of if 1
printf("Couldn't open file for read.\n");
} //end of main
ssize_t read(int fd, void *buf, size_t count);
read reads count bytes from the file. You're asking it to read zero bytes when doing bytesread = read(fd,&c,0);. Change it to bytesread = read(fd,&c,1);
Try this:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(void)
{
int fd;
char c;
int bytesread;
if ((fd = open("hello.txt", O_RDONLY, 0)) != -1) {
while ((bytesread = read(fd, &c, 1)) == 1)
printf("read %d bytes [%c]\n", bytesread, c);
} else
printf("Couldn't open file for read.\n");
return 0;
}
read(fd,&c,0) asks the system to read zero bytes, and it shouldn't be what you want to do.
You should ask the system to read one byte by read(fd,&c,1).
The following server creates a named pipe when it's run like this:
./serverprogram -p nameofthepipe -t 99
the optarg after t indicates a number of threads to be created (not done here).
Anyway, the pipe isn't working here:
/* Open the first named pipe for reading */
int rdfd = open(pipeName, O_RDONLY);
/* Read from the first pipe */
int numread = read(rdfd, command_and_pid, 280);
printf("what's being read is %s \n", command_and_pid); // not printing!!1!
Why?
Server program:
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
int main (int argc, char * argv[])
{
char pipeName[30];
int numThreads;
char command_and_pid[280];
int opcion;
if (argc < 2) {
printf ("ERROR: Missing arguments\n");//
exit(1);
}
opterr = 0;
while ((opcion = getopt (argc, argv, "p:t:w")) != -1)
{
switch (opcion) {
case 'p': // -p indica el nombre del pipe
printf("The name of the pipe is: %s\n",optarg);
strcpy(pipeName, optarg);
break;
case 't'://-t indica los hilos
printf("The number of threads is: %s\n",optarg);
numThreads= atoi(optarg);
break;
case '?':
fprintf(stderr,"no reconozco esa opcion\n");
break;
}
}
int ret_val = mkfifo(pipeName, 0666);
if ((ret_val == -1) && (errno != EEXIST)) {
perror("Error creating the named pipe");
exit (0);
}
/* Open the first named pipe for reading */
int rdfd = open(pipeName, O_RDONLY);
/* Read from the first pipe */
int numread = read(rdfd, command_and_pid, 280);
printf("what's being read is %s \n", command_and_pid); // not printing!!1!
close(rdfd);
return 0;
}
Client program:
#include <unistd.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
int main (int argc, char * argv[])
{
char pipeName[30];
printf("write the name of the pipe used to write to the server \n");
fgets(pipeName,30, stdin);
/* Open the first named pipe for writing */
int wrfd = open(pipeName, O_WRONLY);
printf("write the name of the command you want to execute \n");
char command_and_pid[280];
char command[250];
fgets(command,250, stdin);
puts(command); //quitar
strcpy(command_and_pid,command);
strcat(command_and_pid," ");
int pipeIntId;
char pidstring [30];
int pid= getpid();
sprintf(pidstring,"%d", pid);
strcat(command_and_pid,pidstring);
int written;
written=write(pipeIntId,command_and_pid,280);
//write to the pipe
// send the command and pid
close(pipeIntId); // close write pipe
return 0;
}
In the client, fgets keeps the newline at the end of the line, so you'll need to strip that before opening the file.
Also, in the code as given, you're opening wrfd but writing to pipeIntId, which is uninitialized (though perhaps you are extracting something from a function here).