For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > May 2006 > FIFO synchronization problem









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author FIFO synchronization problem
erik.dassi@gmail.com

2006-05-12, 7:04 pm

Hi, I have a problem related to FIFOs under Linux. I'm developing a
simple application with a server that open his fifo(server_fifo) for
reading and then blocks waiting for writers. When I open a client the
server gets unblocked and reads the messages sent by clients... but the
problem is that the first fgets I do always returns "dirt" and so the
first reply by the server to the client is that the command is wrong.
Going on all the messages are one message after what they should be, so
as I send message 9 I get answer 8, when I send message 10, I get
answer 9 and so on.... someone has an idea on what it could be ? I
could just trash the first read but I wanted to understand what it is,
as I guess it's not right...

thanks to everyone, erik

THIS IS CLIENT CODE

int main(int argc, char *argv[])
{
/* stores informations about logged user and tells if a user is
logged.*/
char logUsername[50];
char logPassword[50];
int isLogged = 0;

/* program variables storing string commands and pointing to
FIFOs.*/
char menuChoice;
char command[512];
char *buffer;
FILE *fpRead;
FILE *fpWrite;

/* opens server fifo for sending commands to server.*/
if((fpWrite = fopen(FIFO_FILE, "w")) == NULL) {
perror("fopen");
exit(1);
}

/* get client PID.*/
char pid[20];
int intpid = getpid();
sprintf(pid,"%d", intpid);

//makes client fifo for server replies.
char clientFifoPath[50] = "/tmp/fifo_";
strcat(clientFifoPath, pid);
mknod(clientFifoPath, S_IFIFO|0666, 0);

/* main program loop for commands sending/reply.*/
while(1) {

sprintf(command,"%s;UREG;%s;%s;\n", pid, username, password);

SendMessage(fpWrite, command);
fpRead = fopen(clientFifoPath, "r");
buffer = GetMessage(fpRead);
if (strcmp(buffer,"UREGSUCC;")) {
printf("\nAll right\n");
}
else {
printf("\nServer replied: %s\n", buffer);
}
fclose(fpRead);
}
}
}

void SendMessage(FILE *fifo, char *message) {

if (fprintf(fifo, "%s", message) < 0) {
printf("Error while writing message!");
}
fflush(fifo);
}

char *GetMessage(FILE *fifo) {
char buffer[512];
return fgets(buffer, sizeof(buffer), fifo);
}

THIS IS SERVER CODE

int main(void) {
FILE *fp;
char *readbuf;

/* Create the FIFO if it does not exist */
umask(0);
mknod(FIFO_FILE, S_IFIFO|0666, 0);

while(1)
{
/* open reception FIFO. */
int fd = open(FIFO_FILE, O_RDONLY);
fp = fdopen(fd, "r");

readbuf = GetMessage(fp);
/*if a message was retrieved, process it.*/
if (readbuf != NULL) {
/*elaborate return string*/
SendMessage(CLIENT_FIFO, message);
}

fclose(fp);
}

return(0);
}

annamalai.gurusami@gmail.com

2006-05-12, 7:04 pm

erik.dassi@gmail.com wrote:
> Hi, I have a problem related to FIFOs under Linux. I'm developing a
> simple application with a server that open his fifo(server_fifo) for


The code that you have posted is not compilable. It is missing the
relevant include files and also some #defines. It would be better if
you have posted a complete program that can be compiled by just
copy-pasting.

> char *GetMessage(FILE *fifo) {
> char buffer[512];
> return fgets(buffer, sizeof(buffer), fifo);
> }


This function returns a pointer to a local variable.

Rgds,
anna

erik.dassi@gmail.com

2006-05-13, 4:01 am

hi these are complete sources:
CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>

//CHIDEDRE PER CLEAN
SCREEN__________________________________
__________________
#include <curses.h>

#define FIFO_FILE "/tmp/MYFIFO"

char *GetMessage(FILE *fifo);
void SendMessage(FILE *fifo, char *message);

int main(int argc, char *argv[])
{
/* stores informations about logged user and tells if a user is
logged.*/
char logUsername[50];
char logPassword[50];
int isLogged =3D 0;

/* program variables storing string commands and pointing to
FIFOs.*/
char menuChoice;
char command[512];
char *buffer;
FILE *fpRead;
FILE *fpWrite;

/* opens server fifo for sending commands to server.*/
if((fpWrite =3D fopen(FIFO_FILE, "w")) =3D=3D NULL) {
perror("fopen");
exit(1);
}

/* get client PID.*/
char pid[20];
int intpid =3D getpid();
sprintf(pid,"%d", intpid);

printf("\nil pid =E8 %s.\n", pid);

//makes client fifo for server replies.
char clientFifoPath[50] =3D "/tmp/fifo_";
strcat(clientFifoPath, pid);
mknod(clientFifoPath, S_IFIFO|0666, 0);

/* main program loop for commands sending/reply.*/
while(1) {

//clear();
printf("\nChe azione si vuole intraprendere ?\n1.Registare nuovo
utente.\n2.Effettuare il login.\n3.Effettuare il
logoff.\n4.Uscire.\nScelta: ");
menuChoice =3D getchar();

switch(menuChoice) {

case '1': { /* USER REGISTRATION PROCEDURE*/

char username[50];
char password[50];
printf("\nInserire il nome utente: ");
scanf("%s", username);
printf("\nInserire la password: ");
scanf("%s", password);
sprintf(command,"%s;UREG;%s;%s;\n", pid, username, password);

SendMessage(fpWrite, command);
fpRead =3D fopen(clientFifoPath, "r");
buffer =3D GetMessage(fpRead);
if (strcmp(buffer,"UREGSUCC;")) {
printf("\nRegistrazione avvenuta correttamente!\n");
}
else {
printf("\nServer replied: %s\n", buffer);
}
fclose(fpRead);
break;
}
case '2': { /* LOGIN PROCEDURE*/

/* if an user is already logged block this new login
procedure.*/
if (isLogged) {
printf("\n\nUn utente =E8 gi=E0 loggato! Disconnetterlo se si
vuole fare un login diverso!\n");
break;
}
printf("\nInserire il nome utente: ");
scanf("%s", logUsername);
printf("\nInserire la password: ");
scanf("%s", logPassword);
sprintf(command,"%s;ULOGIN;%s;%s;\n", pid, logUsername,
logPassword);

SendMessage(fpWrite, command);
fpRead =3D fopen(clientFifoPath, "r");
buffer =3D GetMessage(fpRead);
if (strcmp(buffer,"ULOGINSUCC;")) {
printf("\n\nLogin avvenuto correttamente! Benvenuto, %s !\n",
logUsername);
isLogged =3D 1;
}
else {
printf("\nUsername o password errati: hai inserito %s - %s\n",
logUsername, logPassword);
}
fclose(fpRead);

break;
}
case '3': { /* LOGOFF PROCEDURE*/
if (isLogged) {
sprintf(command,"%s;ULOGOFF;%s;%s;\n", pid, logUsername,
logPassword);
SendMessage(fpWrite, command);
fpRead =3D fopen(clientFifoPath, "r");
buffer =3D GetMessage(fpRead);
printf("\nServer replied: %s\n", buffer);
isLogged =3D 0;
fclose(fpRead);
}
else {
printf("\n\nPrima di effettuare il logoff =E8 necessario essere
loggati!\n");
}
break;
}
case '4': { /* QUIT PROCEDURE*/

/* if a user is logged require logoff before quitting.*/
if (isLogged) {
printf("\n\nPrima di uscire =E8 necessario effettuare il
logoff!\n");
break;
}
/* closes open file pointers and quit program.*/
printf("\nBye!\n");
fclose(fpWrite);
/* deletes client fifo from computer.*/
unlink(clientFifoPath);
return 0;
}
default: {
printf("\n\nScelta errata!\n\n");
}
}
}
}

void SendMessage(FILE *fifo, char *message) {

if (fprintf(fifo, "%s", message) < 0) {
printf("Error while writing message!");
}
fflush(fifo);
}

char *GetMessage(FILE *fifo) {
char buffer[512];
return fgets(buffer, sizeof(buffer), fifo);
}

SERVER

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

#define FIFO_FILE "/tmp/MYFIFO"
#define USERS_LIST "usersList.dat"
#define BIBLIOS_LIST "bibliosList.dat"

char *commands [10]=3D {"UREG","ULOGIN","ULOGOFF",
"UGETBOOKLIST","USEARCHBOOK","URESERVEBOOK","UGETRESBOOKLIST"};

void SendMessage(FILE *fifo, char *message);
char *GetMessage(FILE *fifo);

void ProcessMessage(char *message);

int main(void) {
FILE *fp;
char *readbuf;

/* Create the FIFO if it does not exist */
umask(0);
mknod(FIFO_FILE, S_IFIFO|0666, 0);

while(1)
{
/* open reception FIFO. */
int fd =3D open(FIFO_FILE, O_RDONLY);
fp =3D fdopen(fd, "r");

readbuf =3D GetMessage(fp);
/*if a message was retrieved, process it.*/
if (readbuf !=3D NULL) {
ProcessMessage(readbuf);
}



//fscanf(fp, "%s;%s;%s;", pid, username, password);
//pid =3D strtok(readbuf, ";");
//username =3D strtok(NULL, ";");
//password =3D strtok(NULL, ";");
//printf("Received string: %s , %s, %s\n", pid, username,
password);
fclose(fp);
}

return(0);
}

char *GetMessage(FILE *fifo) {
char buffer[512];
return fgets(buffer, sizeof(buffer), fifo);
}

void SendMessage(FILE *fifo, char *message) {
if (fprintf(fifo, "%s", message) < 0) {
printf("Error while writing message!");
}
fflush(fifo);
}


void ProcessMessage(char *message) {

char *command;
char *pid;
FILE *fifo;

//printf("\n1)Hi i'm in ProcessMessage");

//acquire PID in order to know what FIFO to open for reply.
pid =3D strtok(message, ";");
if (pid =3D=3D NULL) {
printf("CLIENT PID NOT SENT, CANNOT ANSWER!");
return;
}
else {

//printf("\npid is %s", pid);
char nam[20] =3D "/tmp/fifo_";
strcat(nam, pid);
printf("\n2)AnswerFifo =3D %s", nam);

//QUI IL FILE VIENE CREATO QUINDI PROBLEMA TROVATO
if ((fifo =3D fopen(nam, "w")) =3D=3D NULL) {
printf("WRONG PID INSERTED, CANNOT ANSWER! %s", nam);
return;
}
// ****************************************
********

command =3D strtok(NULL, ";");
if (command =3D=3D NULL) {
SendMessage(fifo, "CMDFAIL;BADFORM;\n");
fclose(fifo);
return;
}

int commandIndex =3D GetCommandIndex(command);
// printf("\n3)CommandIndex is %d", commandIndex);

switch(commandIndex) {
case 0: {
char *username, *password;
username =3D strtok(NULL, ";");
password =3D strtok(NULL, ";");
if ((username =3D=3D NULL) || (password =3D=3D NULL)) {
SendMessage(fifo, "CMDFAIL;BADFORM;\n");

//scanf("%s", s);
fclose(fifo);
return;
}

printf("user wants to register with username [%s] and password
[%s], pid is [%s]", username, password, pid);
//scanf("%s", s);
SendMessage(fifo,"UREGSUCC;\n");
fclose(fifo);
break;
}
case 1: {
SendMessage(fifo,"ULOGINSUCC;\n");
fclose(fifo);
break;
}
case 2: {
SendMessage(fifo,"ULOGOFF;\n");
fclose(fifo);
break;
}
default: {
SendMessage(fifo, "CMDFAIL;BADFORM;\n");
fclose(fifo);
break;
}
}

}

}

//match the given string command with his numeric index.
int GetCommandIndex(char command []) {
int i =3D 0;
for (i =3D 0; i < 3; i++) {
if (strcmp(commands[i], command) =3D=3D 0) {
//returns command index.
return i;
}
}
//command not found in commands list.
return -1;
}





there are some strings in Italian, it's all control stuff so don't
bother with it.... thanks and excuse me...erik

annamalai.gurusami@gmail.com

2006-05-13, 7:01 pm

erik.dassi@gmail.com wrote:
> hi these are complete sources:


But you haven't corrected for returning a reference of a local
variable. Please read the response completely so that you can benefit.

> switch(menuChoice) {
>
> case '1': { /* USER REGISTRATION PROCEDURE*/
>
> char username[50];
> char password[50];
> printf("\nInserire il nome utente: ");
> scanf("%s", username);
> printf("\nInserire la password: ");
> scanf("%s", password);


The scanf() doesn't read the whitespace characters for the %s format
specifier. So after the above two calls to scanf() there will still be
one newline character left in the input stream. I recommend you read
the scanf() man page.

> buffer = GetMessage(fpRead);
> if (strcmp(buffer,"UREGSUCC;")) {
> printf("\nRegistrazione avvenuta correttamente!\n");
> }


I think the way you have used strcmp() is not correct. For example,

if ( strcmp("same", "same") )
{
// this portion will not be executed
}

Kindly read the manpage of strcmp() as well.

> char *GetMessage(FILE *fifo) {
> char buffer[512];
> return fgets(buffer, sizeof(buffer), fifo);
> }


The function GetMessage() is returning a reference to a local variable.
If you don't know what it means, ask fellow programmers around you.
Or read some good C books. The problems that you have is only because
you do not have a good grasp of the C programming language. It has
got nothing to do with UNIX programming.

Rgds,
anna

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com