Problème de blocage des sockets de domaine unix

J’écris une application divisée en deux parties pour Mac OS X: un démon et un agent. J’utilise un socket unix standard pour communiquer entre le démon et les agents. C’est-à-dire que le socket est créé avec PF_UNIX et SOCK_STREAM .

Lorsque des agents sont créés (chaque fois qu’un utilisateur se connecte), l’une des premières tâches consiste à se connecter au socket. Cela semble fonctionner parfaitement pour le premier agent. Cependant, lorsque le deuxième agent se connecte, le démon rencontre le problème suivant:

J’utilise select() pour vérifier les données qui peuvent être lues. L’appel select() réussit et indique qu’il y a des données à lire. Cependant, lorsque j’appelle recv() il renvoie -1 et errno 35 , ou "Resource temporarily unavailable".

Maintenant, je m’attendrais à ce que ce soit pour un socket non bloquant, mais j’ai vérifié trois fois – je n’ai jamais défini le socket comme étant non bloquant.

Autant que je sache, cela ne se produit que lorsqu’un deuxième agent se connecte à la même socket unix. Si je me limite à un démon et à un agent, tout semble fonctionner parfaitement. Qu’est-ce qui pourrait causer ce comportement étrange?

Cela ressemble un peu à ce que vous essayez de lire du mauvais client fd. C’est difficile à dire sans voir votre code, mais ça sonne aussi un peu dans votre description.

Donc, juste au cas où, voici comment ça marche. Votre serveur se termine par trois descripteurs de fichiers, le socket sur lequel il commence à écouter, puis un descripteur de fichier pour chaque client connecté. Quand il y a quelque chose à lire sur le socket d’origine, cela signifie qu’il y a un nouveau client; on dirait que vous avez cette partie bien. Chaque client connecté vous donne alors sa propre fd indépendante à lire / écrire. L’appel de select () renverra si l’ un d’entre eux est prêt à être lu; vous devez ensuite vérifier chaque fd dans la variable readfds de select avec FD_ISSET () pour voir si elle a réellement des données à lire.

Vous pouvez voir un exemple de base de ce type de code ici .