Comment avoir une socket datagram bidirectionnelle locale a un Linux ?
2 réponses
David MENTRE
Bonjour à tous,
Je voudrais faire communiquer 2 processus sur un même Linux (Debian,
noyau 2.6.3) par une socket bidirectionnelle datagram (càd qui conserve
la séparation entre les message, une socket stream m'oblige à refaire la
segmentation).
Après avoir lu un certain nombre de pages de man (unix(7), socket(2),
...) il me semblait que PF_UNIX, SOCK_DGRAM pouvait convenir.
J'ai donc écrit le code suivant. J'arrive à envoyer un message de la
machine B (qui fait le connect()) à la machine A.
Par contre, quand la machine A envoie un message à B, j'ai droit à un
joli :
cannot send message: Transport endpoint is not connected
Est-ce qu'une socket PF_UNIX, SOCK_DGRAM est unidirectionnelle ? Il me
faut ouvrir 2 sockets (A->B et B->A) ?
J'ai oublié une manip' ou option dans le code suivant ?
Est-ce qu'il existe un autre type de socket qui me permet de réaliser ce
que je veux ?
Merci d'avance pour tout coup de main,
Amicalement,
david
my_side = side;
switch (my_side) {
case A_SIDE:
/* on A side, open server socket */
if (debug)
printf("creating A side socket...\n");
com_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
if (com_socket < 0) {
perror("unable to open micom socket");
exit(1);
}
if (bind(com_socket, (struct sockaddr *)&sock_addr,
sizeof(struct sockaddr_un)) < 0) {
perror("unable to bind micom socket (/tmp/micom_A_B already exists?)");
exit(1);
}
if (debug) printf(" done.\n");
break;
case B_SIDE:
/* on B side, connect to the above socket */
if (debug) printf("creating B side socket and connect to A side...\n");
com_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
if (com_socket < 0) {
perror("unable to open micom socket");
exit(1);
}
if (connect(com_socket, (struct sockaddr*)&sock_addr,
sizeof(struct sockaddr_un)) < 0) {
perror("unable to connect to A side");
exit(1);
}
if (debug) printf(" connection made.\n");
break;
--
Pour contacter l'équipe de modération : moderateurs-fcolm@efrei.fr
ATTENTION: Postez DIRECTEMENT vos articles dans le groupe, PAS dans
la liste de distribution des modérateurs.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Brieuc Jeunhomme
> Par contre, quand la machine A envoie un message à B, j'ai droit à un joli :
cannot send message: Transport endpoint is not connected
C'est logique. Tu n'as pas fait de connect(), et tu ne fais pas non plus un sendto(), donc, la machine A n'a aucun moyen de savoir à qui envoyer les données. Il faudrait faire aussi un connect() côté A. Mais un seul des deux process pourra recevoir les messages (A, en l'occurence).
Est-ce qu'il existe un autre type de socket qui me permet de réaliser ce que je veux ?
Je n'en ai jamais eu besoin, mais je pense que tu trouveras ton bonheur dans man socketpair. Autre technique qui pourrait faire ton affaire: les messages Sys V (man msgctl; man msgget; man msgrcv; man msgsnd), mais ça a la réputation d'être buggué sous Linux (les bugs se manifestant quand tu envoies beaucoup de messages en peu de temps).
-- BBP
-- Pour contacter l'équipe de modération : ATTENTION: Postez DIRECTEMENT vos articles dans le groupe, PAS dans la liste de distribution des modérateurs.
> Par contre, quand la machine A envoie un message à B, j'ai droit à un
joli :
cannot send message: Transport endpoint is not connected
C'est logique. Tu n'as pas fait de connect(), et tu ne fais pas non plus
un sendto(), donc, la machine A n'a aucun moyen de savoir à qui envoyer
les données. Il faudrait faire aussi un connect() côté A. Mais un seul
des deux process pourra recevoir les messages (A, en l'occurence).
Est-ce qu'il existe un autre type de socket qui me permet de réaliser ce
que je veux ?
Je n'en ai jamais eu besoin, mais je pense que tu trouveras ton bonheur
dans man socketpair. Autre technique qui pourrait faire ton affaire: les
messages Sys V (man msgctl; man msgget; man msgrcv; man msgsnd), mais ça
a la réputation d'être buggué sous Linux (les bugs se manifestant quand
tu envoies beaucoup de messages en peu de temps).
--
BBP
--
Pour contacter l'équipe de modération : moderateurs-fcolm@efrei.fr
ATTENTION: Postez DIRECTEMENT vos articles dans le groupe, PAS dans
la liste de distribution des modérateurs.
> Par contre, quand la machine A envoie un message à B, j'ai droit à un joli :
cannot send message: Transport endpoint is not connected
C'est logique. Tu n'as pas fait de connect(), et tu ne fais pas non plus un sendto(), donc, la machine A n'a aucun moyen de savoir à qui envoyer les données. Il faudrait faire aussi un connect() côté A. Mais un seul des deux process pourra recevoir les messages (A, en l'occurence).
Est-ce qu'il existe un autre type de socket qui me permet de réaliser ce que je veux ?
Je n'en ai jamais eu besoin, mais je pense que tu trouveras ton bonheur dans man socketpair. Autre technique qui pourrait faire ton affaire: les messages Sys V (man msgctl; man msgget; man msgrcv; man msgsnd), mais ça a la réputation d'être buggué sous Linux (les bugs se manifestant quand tu envoies beaucoup de messages en peu de temps).
-- BBP
-- Pour contacter l'équipe de modération : ATTENTION: Postez DIRECTEMENT vos articles dans le groupe, PAS dans la liste de distribution des modérateurs.
Pascal Dufour
David MENTRE wrote:
Je voudrais faire communiquer 2 processus sur un même Linux (Debian, noyau 2.6.3) par une socket bidirectionnelle datagram (càd qui conserve la séparation entre les message, une socket stream m'oblige à refaire la segmentation).
Après avoir lu un certain nombre de pages de man (unix(7), socket(2), ...) il me semblait que PF_UNIX, SOCK_DGRAM pouvait convenir.
J'ai donc écrit le code suivant. J'arrive à envoyer un message de la machine B (qui fait le connect()) à la machine A.
Cela ne marchera pas si A est différente de B, par définition.
Par contre, quand la machine A envoie un message à B, j'ai droit à un joli :
cannot send message: Transport endpoint is not connected
Est-ce qu'une socket PF_UNIX, SOCK_DGRAM est unidirectionnelle ? Il me faut ouvrir 2 sockets (A->B et B->A) ?
Non, cela fonctionne très bien.
J'ai oublié une manip' ou option dans le code suivant ?
D'après ce que je vois dans le code, vous utilisez "send"/"recv" au lieu de "sendto"/"recvfrom", cela ne peut fonctionner que si la socket est "connectée" (sens particulier dans le cas de SOCK_DGRAM). Dans votre code, B fait un connect, mais pas A.
Ce sont les codes sources du livre de Richard Stevens sur la programmation réseau sous Unix.
Il y a beaucoup de petites subtilités dans la programmation des sockets. Un bon livre est nécessaire pour éviter les mauvaises surprises. Les man pages c'est bien comme référence, mais pour la pédagogie il vaut mieux aller voir ailleur.
-- Pascal.
-- Pour contacter l'équipe de modération : ATTENTION: Postez DIRECTEMENT vos articles dans le groupe, PAS dans la liste de distribution des modérateurs.
David MENTRE wrote:
Je voudrais faire communiquer 2 processus sur un même Linux (Debian,
noyau 2.6.3) par une socket bidirectionnelle datagram (càd qui conserve
la séparation entre les message, une socket stream m'oblige à refaire la
segmentation).
Après avoir lu un certain nombre de pages de man (unix(7), socket(2),
...) il me semblait que PF_UNIX, SOCK_DGRAM pouvait convenir.
J'ai donc écrit le code suivant. J'arrive à envoyer un message de la
machine B (qui fait le connect()) à la machine A.
Cela ne marchera pas si A est différente de B, par définition.
Par contre, quand la machine A envoie un message à B, j'ai droit à un
joli :
cannot send message: Transport endpoint is not connected
Est-ce qu'une socket PF_UNIX, SOCK_DGRAM est unidirectionnelle ? Il me
faut ouvrir 2 sockets (A->B et B->A) ?
Non, cela fonctionne très bien.
J'ai oublié une manip' ou option dans le code suivant ?
D'après ce que je vois dans le code, vous utilisez "send"/"recv" au
lieu de "sendto"/"recvfrom", cela ne peut fonctionner que si la
socket est "connectée" (sens particulier dans le cas de SOCK_DGRAM).
Dans votre code, B fait un connect, mais pas A.
Ce sont les codes sources du livre de Richard Stevens sur la
programmation réseau sous Unix.
Il y a beaucoup de petites subtilités dans la programmation
des sockets. Un bon livre est nécessaire pour éviter les mauvaises
surprises. Les man pages c'est bien comme référence, mais pour la
pédagogie il vaut mieux aller voir ailleur.
--
Pascal.
--
Pour contacter l'équipe de modération : moderateurs-fcolm@efrei.fr
ATTENTION: Postez DIRECTEMENT vos articles dans le groupe, PAS dans
la liste de distribution des modérateurs.
Je voudrais faire communiquer 2 processus sur un même Linux (Debian, noyau 2.6.3) par une socket bidirectionnelle datagram (càd qui conserve la séparation entre les message, une socket stream m'oblige à refaire la segmentation).
Après avoir lu un certain nombre de pages de man (unix(7), socket(2), ...) il me semblait que PF_UNIX, SOCK_DGRAM pouvait convenir.
J'ai donc écrit le code suivant. J'arrive à envoyer un message de la machine B (qui fait le connect()) à la machine A.
Cela ne marchera pas si A est différente de B, par définition.
Par contre, quand la machine A envoie un message à B, j'ai droit à un joli :
cannot send message: Transport endpoint is not connected
Est-ce qu'une socket PF_UNIX, SOCK_DGRAM est unidirectionnelle ? Il me faut ouvrir 2 sockets (A->B et B->A) ?
Non, cela fonctionne très bien.
J'ai oublié une manip' ou option dans le code suivant ?
D'après ce que je vois dans le code, vous utilisez "send"/"recv" au lieu de "sendto"/"recvfrom", cela ne peut fonctionner que si la socket est "connectée" (sens particulier dans le cas de SOCK_DGRAM). Dans votre code, B fait un connect, mais pas A.
Ce sont les codes sources du livre de Richard Stevens sur la programmation réseau sous Unix.
Il y a beaucoup de petites subtilités dans la programmation des sockets. Un bon livre est nécessaire pour éviter les mauvaises surprises. Les man pages c'est bien comme référence, mais pour la pédagogie il vaut mieux aller voir ailleur.
-- Pascal.
-- Pour contacter l'équipe de modération : ATTENTION: Postez DIRECTEMENT vos articles dans le groupe, PAS dans la liste de distribution des modérateurs.