web-dev-qa-db-fra.com

Socketpair () dans C / Unix

J'ai 2 applications sur le même système dont j'ai besoin pour 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.

J'arrache mes 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 le fait que je suis un programmeur C novice n'aide certainement pas la situation.

J'ai googlé pendant les 48 dernières heures, lu des tutoriels, etc., mais je ne parviens toujours pas à l'obtenir. Je comprends le concept, mais le code est tout simplement trop déroutant. 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 donner un exemple (si simple qu'un élève de 5e pourrait comprendre) ou me diriger vers un bon tutoriel?

30
NASA Intern

Vous pouvez utiliser socketpair uniquement lorsque vous créez les deux processus, comme ceci:

  1. call socketpair - vous avez maintenant deux descripteurs de fichier socket (deux extrémités d'un seul tube)
    • désigner une extrémité pour être parent et une pour être enfant fin. Peu importe lequel, faites simplement un choix et respectez-le plus tard
  2. appelez fork - vous avez maintenant deux processus
    1. si fork a renvoyé zéro, vous êtes l'enfant. Fermez le descripteur de fichier parent, conservez le descripteur enfant et utilisez-le comme extrémité du processus
    2. si fork retourne différent de zéro, vous êtes le parent. Fermez le descripteur de fichier enfant, conservez-le parent et utilisez-le comme extrémité 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 avoir appelé fork. Si parent appelle write sur son socket, enfant pourra lire ces données depuis its 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 qu'il ne s'agit que d'un exemple de code: j'ai omis toute vérification d'erreur et un protocole de flux sensible.


Si vous voulez que deux programmes séparés communiquent (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:

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

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

56
Useless

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

Si vous voulez faire la communication entre des processus non liés (dans le sens de la filiation), vous devez utiliser socket, bind et connect pour créer une socket d'écoute dans un processus et créer un socket client pour s'y connecter dans l'autre processus.

7
R..

Pour communiquer entre deux processus, oui, la communication inter-processus ou IPC est ce que vous devez rechercher. Les sockets ne sont qu'une des méthodes de communication et sont utiles si vous devez implémenter un à un). plusieurs connexions. Signifie, un processus serveur qui communique avec de nombreux processus clients de manière réponse à la demande. 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 trouverez les facile en temps voulu :-))

Pour votre problème, je vous suggère d'utiliser des mécanismes plus simples IPC comme Pipe, FIFO, Message Queue. Je ne sais pas comment vous êtes parvenu à la conclusion d'utiliser socketpair. Puisque vous n'avez rien mentionné dans le conception ou type de IPC vous avez besoin ET bassed sur le niveau d'utilisation, je recommande fortement de regarder dans Pipe ou FIFO exemples de codes dans un livre ou Internet. Ils devraient regarder beaucoup plus facile à implémenter et à travailler plus rapidement que les sockets.

1
Groovy