Lire/Écrire struct la méthode fifo en C
Je suis en train de passer entre les structures des processus à l'aide des canaux nommés. Je me suis coincé en essayant d'ouvrir le tuyau de non-blocage de la mode. Voici mon code pour l'écriture de la fifo:
void writeUpdate() {
//Create fifo for writing updates:
strcpy(fifo_write, routing_table->routerName);
//Check if fifo exists:
if(access(fifo_write, F_OK) == -1 )
fd_write = mkfifo(fifo_write, 0777);
else if(access(fifo_write, F_OK) == 0) {
printf("writeUpdate: FIFO %s already exists\n", fifo_write);
//fd_write = open(fifo_write, O_WRONLY|O_NONBLOCK);
}
fd_write = open(fifo_write, O_WRONLY|O_NONBLOCK);
if(fd_write < 0)
perror("Create fifo error");
else {
int num_bytes = write(fd_write, routing_table, sizeof(routing_table));
if(num_bytes == 0)
printf("Nothing was written to FIFO %s\n", fifo_write);
printf("Wrote %d bytes. Sizeof struct: %d\n", num_bytes,sizeof(routing_table)+1);
}
close(fd_write);
}
routing_table est un pointeur de ma structure, il est alloué, donc il n'y a pas de prob avec le nom de la fifo ou qch comme ça.
Si j'ouvre la fifo sans l'option O_NONBLOCK, il écrit qch pour la première fois, mais ensuite il bloque parce que je vais avoir des problèmes de lecture de la struct trop. Et après la première fois, la première fifo est créé, mais d'autres fifo apparaissent, nommée '.', '..'.
Avec option O_NONBLOCK ensemble, il crée le fifo, mais jette toujours un message d'erreur: "rien de tel appareil ou de l'adresse'. Une idée de pourquoi cela se produit? Merci.
EDIT: Ok, si je suis clair, maintenant, sur l'ouverture de la fifo, mais j'ai un autre problème, en fait la lecture/écriture de la structure de la fifo était ma question de départ. Mon code pour lire la struct:
void readUpdate() {
struct rttable *updateData;
allocate();
strcpy(fifo_read, routing_table->table[0].router);
//Check if fifo exists:
if(access(fifo_read, F_OK) == -1 )
fd_read = mkfifo(fifo_read, 777);
else if(access(fifo_read, F_OK) == 0) {
printf("ReadUpdate: FIFO %s already exists\n Reading from %s\n", fifo_read, fifo_read);
}
fd_read = open(fifo_read, O_RDONLY|O_NONBLOCK);
int num_bytes = read(fd_read, updateData, sizeof(updateData));
close(fd_read);
if(num_bytes > 0) {
if(updateData == NULL)
printf("Read data is null: yes");
else
printf("Read from fifo: %s %d\n", updateData->routerName, num_bytes);
int result = unlink(fifo_read);
if(result < 0)
perror("Unlink fifo error\n");
else {
printf("Unlinking successful for fifo %s\n", fifo_read);
printf("Updating table..\n");
//update(updateData);
print_table_update(updateData);
}
} else
printf("Nothing was read from FIFO %s\n", fifo_read);
}
Il ouvre la fifo et essaie de lire, mais il semble que rien n'est dans la fifo, bien que dans writeUpdate la première fois qu'il dit qu'il a écrit 4 octets (ce qui semble mal aussi). À la lecture, la première fois autour d'elle imprime 'a' et puis num_bytes est toujours <=0.
J'ai regardé autour et ne se trouve que cet exemple, avec une simple lecture/écriture, est-il qch plus nécessaire lors de l'écriture d'une structure?
Mon struct ressemble à ceci:
typedef struct distance_table {
char dest[20]; //destination network
char router[20]; //via router..
int distance;
} distance_table;
typedef struct rttable {
char routerName[10];
char networkName[20];
struct distance_table table[50];
int nrRouters;
} rttable;
struct rttable *routing_table;
Vous devez vous connecter pour publier un commentaire.
"Pas un tel dispositif ou d'adresse" est le
ENXIO
message d'erreur. Si vous regardez laouvrir
page de manuel, vous verrez que cette erreur est signalée, en particulier si:qui est exactement votre situation. Ainsi, le comportement que vous voyez est normal: vous ne pouvez pas écrire (sans blocage) à un tuyau qui n'a pas de lecteurs. Le noyau ne sera pas de la mémoire tampon de vos messages si rien n'est connecté à la canalisation pour la lecture.
Alors assurez-vous de commencer le "consommateur(s)" avant le "producteur", ou de supprimer la non-option de blocage sur le producteur.
BTW: à l'aide de
access
est, dans la plupart des cas, à vous ouvrir à le temps de vérification et d'utilisation questions. Ne l'utilisez pas. Essayez lemkfifo
- si cela fonctionne, vous êtes bon. Si elle échoue avecEEXISTS
, vous êtes trop bonne. Si elle ne parvient pas autrement, de nettoyage et de renflouer.Pour la deuxième partie de votre question, cela dépend vraiment complètement sur comment exactement les données que vous essayez d'envoyer est structuré. La sérialisation d'un hasard struct en C n'est pas du tout facile, surtout si elle contient les données variables (comme
char *
s par exemple).Si vous struct ne contient que des types primitifs (et pas de pointeur), et les deux parties sont sur la même machine (et compilé avec le même compilateur), puis un raw
write
sur un côté etread
de l'autre, de l'ensemble de la structure devrait fonctionner.Vous pouvez regarder C - techniques de Sérialisation pour plus de types de données complexes par exemple.
Concernant votre exemple: vous vous êtes mélangé entre les pointeurs de vos structures et de la plaine des structures.
Sur l'écriture, vous avez:
C'est incorrect car
routing_table
est un pointeur. Vous avez besoin de:Même chose sur le côté lecture. Sur la réception de taille, vous êtes aussi de ne pas allouer
updateData
aussi loin que je peux dire. Vous devez le faire aussi (avecmalloc
, et n'oubliez pas de le libérer).open
, vous savez il n'y a pas de consommation, donc il n'y a pas de point dans l'écriture - pas de lecture sur l'autre extrémité. si votre approche fonctionne avecO_NONBLOCK
- vous savez que le consommateur ne l'a pas lu.