|
From: erik.dassi on 12 May 2006 15:29 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); }
From: annamalai.gurusami on 12 May 2006 16:32 erik.dassi(a)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
From: erik.dassi on 13 May 2006 03:18 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 = 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); printf("\nil pid è %s.\n", pid); //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) { //clear(); printf("\nChe azione si vuole intraprendere ?\n1.Registare nuovo utente.\n2.Effettuare il login.\n3.Effettuare il logoff.\n4.Uscire.\nScelta: "); menuChoice = 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 = fopen(clientFifoPath, "r"); buffer = 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 è già 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 = fopen(clientFifoPath, "r"); buffer = GetMessage(fpRead); if (strcmp(buffer,"ULOGINSUCC;")) { printf("\n\nLogin avvenuto correttamente! Benvenuto, %s !\n", logUsername); isLogged = 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 = fopen(clientFifoPath, "r"); buffer = GetMessage(fpRead); printf("\nServer replied: %s\n", buffer); isLogged = 0; fclose(fpRead); } else { printf("\n\nPrima di effettuare il logoff è 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 è 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]= {"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 = open(FIFO_FILE, O_RDONLY); fp = fdopen(fd, "r"); readbuf = GetMessage(fp); /*if a message was retrieved, process it.*/ if (readbuf != NULL) { ProcessMessage(readbuf); } //fscanf(fp, "%s;%s;%s;", pid, username, password); //pid = strtok(readbuf, ";"); //username = strtok(NULL, ";"); //password = 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 = strtok(message, ";"); if (pid == NULL) { printf("CLIENT PID NOT SENT, CANNOT ANSWER!"); return; } else { //printf("\npid is %s", pid); char nam[20] = "/tmp/fifo_"; strcat(nam, pid); printf("\n2)AnswerFifo = %s", nam); //QUI IL FILE VIENE CREATO QUINDI PROBLEMA TROVATO if ((fifo = fopen(nam, "w")) == NULL) { printf("WRONG PID INSERTED, CANNOT ANSWER! %s", nam); return; } //************************************************ command = strtok(NULL, ";"); if (command == NULL) { SendMessage(fifo, "CMDFAIL;BADFORM;\n"); fclose(fifo); return; } int commandIndex = GetCommandIndex(command); // printf("\n3)CommandIndex is %d", commandIndex); switch(commandIndex) { case 0: { char *username, *password; username = strtok(NULL, ";"); password = strtok(NULL, ";"); if ((username == NULL) || (password == 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 = 0; for (i = 0; i < 3; i++) { if (strcmp(commands[i], command) == 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
From: annamalai.gurusami on 13 May 2006 15:50 erik.dassi(a)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
|
Pages: 1 Prev: "is not an identifier" Next: gethostbyaddr / nslookup failed on AIX 5.3 |