D'écriture/de Lecture/de FIFO de fichiers linux
J'ai été d'essayer d'envelopper ma tête autour de la FIFO, et est venu avec un programme simple de serveur et de client.
Je n'essaie pas de faire quelque chose de compliqué, juste pour avoir un processus qui va jouer un rôle de "serveur", ce processus va "écouter" tous les messages livrés par un autre processus; le client.
Voici ce que j'ai écrit:
serveur.c
#include<stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#define INGOING "clientToServer.fifo"
#define BUFFER 200
int main(int argc, char *argv[]) {
char in[BUFFER];
mkfifo(INGOING, 0666);
printf("Welcome to server.\n");
printf("channel for sending messages to server is %s\n", INGOING);
int in_fd=open(INGOING, O_RDONLY);
if (in_fd==-1) {
perror("open error");
exit(-1);
}
while (read(in_fd, in, BUFFER)>0) {
printf("You sent %s to server.\n", in);
}
return 2;
}
Comme vous pouvez le voir, c'est assez simple, quand j'ai couru ce fond avec ./server.out&
il est bloqué à la read
appel et attendre quelqu'un pour écrire pour clientToServer.fifo
. so far so good.
Maintenant, considérons le client final:
client.c
#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#define BUFFER 200
int main(int argc, char *argv[]) {
char input[BUFFER]={0};
int out_fd=open("clientToServer.fifo", O_WRONLY);
if (out_fd==-1) {
perror("open error");
}
while (1) {
printf("What would you like to send to server? (send Quit to quit)\n");
fgets(input, BUFFER, stdin);
if (input[strlen(input)-1]=='\n') {
input[strlen(input)-1]='#include<stdio.h>
#include<fcntl.h>
#include<string.h>
#define BUFFER 200
int main(int argc, char *argv[]) {
char input[BUFFER]={0};
int out_fd=open("clientToServer.fifo", O_WRONLY);
if (out_fd==-1) {
perror("open error");
}
while (1) {
printf("What would you like to send to server? (send Quit to quit)\n");
fgets(input, BUFFER, stdin);
if (input[strlen(input)-1]=='\n') {
input[strlen(input)-1]='\0';
}
if (strcmp(input, "Quit")==0) {
printf("Bye!");
break;
}
if (write(out_fd, input, strlen(input))==-1) {
perror("write error");
}
}
return 1;
}
';
}
if (strcmp(input, "Quit")==0) {
printf("Bye!");
break;
}
if (write(out_fd, input, strlen(input))==-1) {
perror("write error");
}
}
return 1;
}
C'est le client. également assez simple code. quand je le lance avec ./a.out
de la coquille, il fonctionne, il envoie le message, et le server.out
processus imprime You sent %s to server.
Problème c'est que quand j'envoie Quit
par le client vers le serveur, bien que la a.out
processus se termine, comme souhaité, les while
boucle dans le server.out
les pauses. sens, la read
ne bloque plus le server.out
processus et attend d'autres clients, au lieu de cela, le serveur de fin du programme, la collaboration avec le client.
Pourquoi est-ce arrivé? ne pas le read
suspendre la server.out
nouveau, même après la a.out
processus se termine?
printf
dans le serveur d'impression un des intermédiaires de la chaîne.donc:
write(out_fd, input, strlen(input)+1)
?No:
int nbytes; while ((nbytes = read(in_fd, in, sizeof(in))) > 0) printf("You sent [%.*s] to the server\n", nbytes, in);
où les crochets délimitent les données qui ont été envoyées (et sont donc facultatif).OriginalL'auteur so.very.tired | 2014-05-02
Vous devez vous connecter pour publier un commentaire.
En fait il bloque à la
open
. C'est la façon dont les Fifo de travail. Leopen
(en mode de blocage) va bloquer jusqu'à ce que quelque chose s'ouvre FIFO sur l'autre extrémité.Encore une fois, ce comportement est normal. Un seul processus client est connecté à la FIFO alors, quand il ferme sa fin, alors EOF est envoyé et le serveur se ferme. Si plusieurs clients sont attachés à la FIFO en même temps, vous ne pourrez pas voir les expressions du FOLKLORE jusqu'à ce que le dernier client de la ferme. Si vous voulez une longue course serveur de servir plusieurs clients en permanence la meilleure façon d'accomplir est d'ouvrir le serveur du FIFO en lecture/écriture. De cette façon il y a toujours un lecteur/enregistreur - le serveur lui-même - et vous ne pourrez pas voir les expressions du FOLKLORE quand même le dernier client quitte. Quand il est temps pour arrêter le serveur, puis fermez l'extrémité appropriée dans le serveur et laisser la nature suivre son cours comme les véritables clients de cesser de fumer.
Je ne suis pas sûr qu'il y est un manuel de soi pour n'importe quel de ces trucs. Il n'y a pas de remplacement pour une bonne, détaillé d'unix et itératif, à proximité de la lecture des pages de manuel. Il y a beaucoup de matières de source de qualité variable sur le web. Celui qui semble être hautement considéré est Beej Guides
Il semble que exactement ce dont j'ai besoin! 🙂
OriginalL'auteur Duck
Lorsque le client quitte il ferme la connexion du tuyau, ce qui provoque la
lire
fonction dans le serveur pour revenir0
qui sort de la boucle.read
quand j'ai couruserver.out
d'abord? il n'y avait pas tous les raccords de tuyau avant d'exécutera.out
.OriginalL'auteur Some programmer dude