Socketpair () en C/Unix

J'ai 2 applications sur le même système que j'ai besoin de communiquer d'avant en arrière. D'après mes recherches, je crois que cela s'appelle la Communication inter-processus et l'utilisation de socketpair() est la meilleure méthode pour mon problème.

Je me déchire les cheveux (littéralement) en essayant de commencer à créer des sockets avec socketpair() en C. D'après ce que je comprends, les sockets sont un sujet très complexe et être un programmeur C novice n'aide sûrement pas la situation.

J'ai googlé pour les dernières 48 heures, lire des tutoriels, etc, mais je ne peux toujours pas l'obtenir. Je comprends le concept, mais le code est trop confus. J'ai lu cet article plusieurs fois: http://beej.us/guide/bgnet/html/single/bgnet.html , mais ce n'est pas assez simple.

Quelqu'un peut-il fournir un exemple (si simple qu'un élève de 5e année pourrait comprendre) ou me diriger vers un bon tutoriel?

23
demandé sur Sandburg 2012-07-13 01:39:23

4 réponses

Vous pouvez utiliser {[1] } uniquement lorsque vous créez les deux processus, comme ceci:

  1. call socketpair - Maintenant, vous avez deux descripteurs de fichier socket (deux extrémités d'un seul tuyau)
    • désigner un bout à l' parent, à la child fin. Peu importe qui, il suffit de faire un choix et de s'y tenir plus tard
  2. appelez fork - Maintenant vous avez deux processus
    1. Si fork renvoie zéro, vous êtes l'enfant. Fermez le fichier parent descripteur, gardez leenfant descripteur, et l'utiliser comme fin de ce processus du tuyau
    2. Si fork renvoyé non nul, vous êtes le parent. Fermez le descripteur de fichierenfant , conservez le parent et utilisez-le comme fin du tuyau
  3. Vous avez maintenant deux processus, chacun a un descripteur de fichier représentant différentes extrémités du même canal. Notez que les deux processus exécutent le même programme, mais ils ont suivi une branche différente après j'appelle fork. Si parent appelle write sur son socket, enfant pourra lire ces données depuis son socket , et vice-versa

Voici une traduction directe en code:

void child(int socket) {
    const char hello[] = "hello parent, I am child";
    write(socket, hello, sizeof(hello)); /* NB. this includes nul */
    /* go forth and do childish things with this end of the pipe */
}

void parent(int socket) {
    /* do parental things with this end, like reading the child's message */
    char buf[1024];
    int n = read(socket, buf, sizeof(buf));
    printf("parent received '%.*s'\n", n, buf);
}

void socketfork() {
    int fd[2];
    static const int parentsocket = 0;
    static const int childsocket = 1;
    pid_t pid;

    /* 1. call socketpair ... */
    socketpair(PF_LOCAL, SOCK_STREAM, 0, fd);

    /* 2. call fork ... */
    pid = fork();
    if (pid == 0) { /* 2.1 if fork returned zero, you are the child */
        close(fd[parentsocket]); /* Close the parent file descriptor */
        child(fd[childsocket]);
    } else { /* 2.2 ... you are the parent */
        close(fd[childsocket]); /* Close the child file descriptor */
        parent(fd[parentsocket]);
    }
    exit(0); /* do everything in the parent and child functions */
}

Veuillez noter que ce n'est qu'un exemple de code: j'ai omis toute vérification des erreurs et un protocole de flux sensible.


Si vous voulez Deux programmes séparés pour communiquer (par exemple. vous avez un exécutable appelé client, et un appelé serveur), vous ne pouvez pas utiliser ce mécanisme. Au lieu de cela, vous pourriez:

  • utilisez des sockets UNIX (où un tube IPC sur un hôte est identifié par un nom de fichier - cela ne fonctionne que si client et serveur fonctionnent sur la même machine)
  • ou utilisez des sockets TCP/IP (où une adresse IP et un port identifient le tuyau, et le client et le serveur peuvent être sur des machines différentes)

Si vous n'avez pas spécifiquement besoin de sockets, et vous êtes heureux d'exiger que les clients et serveur exécuter sur la même machine, vous pouvez également utiliser la mémoire partagée, ou les files d'attente de messages.

50
répondu Useless 2014-06-05 17:43:41

socketpair crée une paire anonyme de sockets, généralement des sockets unix/locaux, qui ne sont utiles que pour la communication entre un processus parent et enfant ou dans d'autres cas où les processus qui doivent les utiliser peuvent hériter des descripteurs de fichier d'un ancêtre commun.

Si vous allez faire la communication entre les processus non liés (dans le sens de la filiation), vous devez utiliser socket, bind, et connect pour créer un socket d'écoute dans un processus et créer un socket client pour connectez-vous à lui dans l'autre processus.

6
répondu R.. 2012-07-12 21:47:41

Pour communiquer entre deux processus, oui, la Communication inter processus ou IPC est ce que vous devriez rechercher. Les Sockets ne sont qu'une des méthodes de communication et sont utiles si vous devez implémenter une connexion un à plusieurs. Signifie, un processus serveur qui communique avec de nombreux processus clients d'une manière demande-réponse. Comme vous êtes un débutant à IPC, il est compréhensible que les adresses de socket et les détails impliqués puissent sembler difficiles à saisir. (Bien que vous les trouverez faciles dans délai: -))

Pour votre problème, je vous suggère d'utiliser des mécanismes IPC plus simples comme Pipe, FIFO, file D'attente de messages. Je ne sais pas comment vous êtes arrivé à la conclusion d'utiliser socketpair. Puisque vous n'avez pas mentionné quoi que ce soit autour de la conception ou du type D'IPC dont vous avez besoin et bassed sur le niveau d'utilisation, je recommande fortement de regarder dans les codes exemples de tuyaux ou de FIFO dans un livre ou internet. Ils devraient être beaucoup plus faciles à implémenter et fonctionner plus rapidement que les sockets.

1
répondu Groovy 2012-07-14 19:25:45

Utilisez TCP / IP. Bien qu'il existe d'autres mécanismes IPC disponibles (tels que les sockets de domaine Unix et SysV IPC), vous êtes mieux avec TCP/IP pour de nombreuses raisons. Voici quelques-uns:

  1. Il y a beaucoup de tutoriels et d'autres informations sur le web décrivant comment faire TCP / IP
  2. les systèmes modernes, et en particulier Linux et * BSD, n'imposent aucune pénalité significative pour l'utilisation de TCP / IP par rapport, disons, aux sockets de domaine Unix ou même à SYSV IPC.
  3. Il existe un certain nombre de bibliothèques et de frameworks que vous pouvez utiliser pour les applications communiquant via TCP / IP.

Le seul cas où je n'utiliserais pas TCP / IP pour communiquer entre deux "programmes" est le cas où ils sont vraiment des threads plutôt que des programmes séparés.

-1
répondu James Youngman 2012-07-12 21:48:40