1. #1
    Nouveau membre du Club
    Homme Profil pro
    ingenieur calcul haute performance
    Inscrit en
    février 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingenieur calcul haute performance
    Secteur : Enseignement

    Informations forums :
    Inscription : février 2013
    Messages : 51
    Points : 35
    Points
    35

    Par défaut Regroupement des lectures de socket sur readv asynchrone

    Bonjour a tous,

    Je souhaite écrire un serveur tcp asynchrone, ce serveur doit parfois recevoir des données.
    Je ne connaît pas a l'avance la taille des données a recevoir, ce qui n'est pas forcément un problème car il reçoit en premier lieu un entier d'un type déterminé (et dont la taille ne varie pas) qui contient la taille des données qui vont suivre.

    Je voudrait que tout cela soit asynchrone, donc un petit coup de fcntl et hop le descripteur est non bloquant.
    L'idée serait de regrouper tout les read qui vont suivre en un seul, on peut faire ça avec readv:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ssize_t readv(int fd, const struct iovec *iov, int iovcnt);
    Si j’écris ce code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    size_t size = 0;
    char* data = NULL;
     
    data = malloc(size * sizeof(char));
     
    struct iovec v[2];
     
    v[0].iov_base = &size;
    v[0].iov_len = sizeof(size_t);
    v[1].iov_base = data;
    v[1].iov_len = *(v[0].iov_base) * sizeof(char);
     
    readv(socket, v, 2);
    Je sait que ça ne peut pas fonctionner entre deux machines little et big endian, 32 et 64 bits, pour la simplicité je n'est pas mis les macros d'usage pour ces transformations (de toute façon il n'y a pas les headers..).

    L'appel système va il utiliser la valeur size qu'il a récupéré dans la première lecture pour faire la seconde?
    A moins qu'il recopie le tableau au départ auquel cas la seconde lecture sera de 0 octets.


    PS: La plateforme c'est Linux et du récent..

  2. #2
    Membre expert
    Inscrit en
    mars 2005
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 1 027
    Points : 3 026
    Points
    3 026

    Par défaut

    Non, tu ne peux pas insérer de traitement au sein de l'opération effectuée par readv. Si le buffer de destination est trop court (à moins d'imposer une contrainte sur la longueur des messages), tu devras donc de toute manière répéter la lecture.

    Pourquoi ne pas tout simplement désérialiser le flux dans un seul et unique buffer de lecture de manière classique via read / recv ?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    ingenieur calcul haute performance
    Inscrit en
    février 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : ingenieur calcul haute performance
    Secteur : Enseignement

    Informations forums :
    Inscription : février 2013
    Messages : 51
    Points : 35
    Points
    35

    Par défaut

    je ne connais pas du tout la solution que tu propose, développe...

  4. #4
    Membre expert
    Inscrit en
    mars 2005
    Messages
    1 027
    Détails du profil
    Informations forums :
    Inscription : mars 2005
    Messages : 1 027
    Points : 3 026
    Points
    3 026

    Par défaut

    Je propose simplement de ne pas utiliser readv. Cet appel (scatter) est justifié soit par des contraintes bas niveau sur l'architecture du programme (allocations non contigües), soit par le besoin de dispatcher les informations d'une même source à différents systèmes de manière atomique. Tu ne sembles pas ici être concerné ni par un cas, ni par l'autre si j'en crois ton exemple.

    D'où ma suggestion : fais comme dans 99% des cas, à savoir récupère toutes les données disponibles d'un bloc et traite-les séquentiellement.

  5. #5
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 4 517
    Points : 18 028
    Points
    18 028

    Par défaut

    +1 pour Matt, readv ne sert strictement à rien.
    Si ton protocole envoit la taille suivi des données, mon dernier article traite précisément de ça.
    En fait je n'ai jamais vu readv utilisé.

    Et ce que tu as écrit est totalement éronné : v[1].iov_len = *(v[0].iov_base) * sizeof(char); vaut un beau 0, de même que data = malloc(size * sizeof(char)); alloue exactement rien du tout.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. [Perl] lecture/écriture simultanées sur une socket
    Par sephiburp dans le forum Programmation et administration système
    Réponses: 10
    Dernier message: 16/10/2007, 10h25
  2. Réponses: 9
    Dernier message: 19/04/2007, 16h14
  3. Réponses: 2
    Dernier message: 23/08/2006, 16h24
  4. [Socket][C++]Utilisation des sockets sur internet
    Par ChriGoLioNaDor dans le forum Développement
    Réponses: 8
    Dernier message: 13/01/2006, 21h38
  5. Réponses: 2
    Dernier message: 10/08/2005, 09h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo