IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

envoyer de gros fichier entre serveur et client(et vice versa)


Sujet :

C++

  1. #1
    Membre à l'essai
    Homme Profil pro
    Lille
    Inscrit en
    Janvier 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Lille

    Informations forums :
    Inscription : Janvier 2007
    Messages : 17
    Points : 17
    Points
    17
    Par défaut envoyer de gros fichier entre serveur et client(et vice versa)
    Bonjour à tous, je travaille en ce moment à un projet dans le cadre de mes études. Mes camarades et moi avons implémenter un réseau qui propose aux utilisateurs de télécharger des fichiers du serveur (et l'upload de leur fichier sur le serveur). Pour l'envoi de fichier large, il me semble qu'il vaudrait mieux les découper affin d'empecher le bloquage de l'envoie/réception sur les sockets de nouveau messages pour l'utilisateur.

    Nous travaillons sur des systèmes Ubuntu ; pour faire simple, notre serveur cré pour tout nouvel utilisateur un processus (via un fork) qui va gérer les les envois des messages en provenance de cet utilisateur (transmission des requètes de l'utilisateur au bon processus de gestion, un par 'service' rendu par le serveur) et la réception de message (les 'réponses' des différents processus de gestion).

    Le téléchargement étant l'un des services rendu par le serveur, je voudrais connaitre votre avis à tous quand à la meilleur stratégie à adopter pour gérer ce service. Une possbilité serait de 'pré-couper' les fichiers et de les envoyer les uns après les autres. Autre problème : les send/recv ne fonctionnent qu'avec des string (char*), suis-je donc obligé de transformer mes fichier en string et de les découper 'à l'avance' en paquet affin de les envoyer au utilisateur le quand ils le désirent, qui de leur coté devrons être capable de les coller et de les rentransformer en leur format originel... ?

    Toute aide sera le bienvenu, merci d'avance
    jeancparis@hotmail.com

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Les send/recv n'utilisent pas de chaines de caractères, mais des octets. Il se trouve juste que le mot clé assimilé aux octets en C c'est char
    Ensuite, on dirait que tu va stocker bien des données avec ton prédécoupage. Pourquoi en as tu tant besoin? Soit M la taille de ton buffer, tu ouvres ton fichier en binaire, charges M octets dans le buffer, envoies les M octets puis tu recommences. C'est pas plus compliqué que ça.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Lille
    Inscrit en
    Janvier 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Lille

    Informations forums :
    Inscription : Janvier 2007
    Messages : 17
    Points : 17
    Points
    17
    Par défaut ok
    je pensais (pour je ne sais quelle raison) qu'on ne pouvait envoyer que des strings...
    Pas de découpage nécessaire ; on pense créer alors un nouveau socket pour le téléchargement affin de ne pas bloquer les autres send/recv
    Cette logique te semble correcte ?

    merci pour ton aide

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Si tu commences à créer de nouvelles sockets sur d'autres ports, ça va faire bizarre et poser des problèmes. Quand une socket type serveur reçoit une demande de connexion, elle crée immédiatement une socket type client pour dialoguer avec le client, il suffit alors de passer cette nouvelle socket à un thread dédié au client puis le thread en cours reprend son attente de nouveaux clients.
    Par contre, si vous utilisez du multi processus, je ne suis pas sur qu'on puisse faire passer un descripteur de socket d'un processus à l'autre, tu vas peut-être être dans l'obligation de l'ouvrir ton nouveau port (ou alors tu fais un serveur mono-connexion, ça dépend de ce que ton prof te demande ), mais ça ferait vraiment pas clean, faudrait ouvrir un port aléatoire sur ta machine et tu aurais vite un truc ingérable - bref on fait jamais comme ça en pratique.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Lille
    Inscrit en
    Janvier 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Lille

    Informations forums :
    Inscription : Janvier 2007
    Messages : 17
    Points : 17
    Points
    17
    Par défaut notre logique
    Comme je t'avais expliqué plus tôt, pour chaque nouvel utilisateur accepté, le serveur cré un nouveau processus. On pense donc que, lors d'une demande de téléchargement acceptée par le serveur, envoyer un message à l'utilisateur, lui demandent d'établire une nouvelle connexion. Cette connexion sera accepté comme précédamment et un nouveau processus sera donc créé. Ce dernier ne servira qu'à transmettre le fichier à l'utilisateur.
    Cette manière te parrait-elle propre ?

    merci d'avance

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Ben non justement, comme je te dis ça va créer un grand nombre de sockets type serveur ce qu'on ne fait jamais (le pire cas est celui de ftp qui en utilise 2, et c'est déja réputé pas pratique à administrer dans les firewall). La meilleure solution serait d'utiliser des threads (je crois vraiment que deux processus ne peuvent pas s'échanger de descripteur de socket, ça doit être comme pour les fichiers).
    Bon, si c'est un petit dossier pour l'école je dis pas mais si c'est pour un vrai programme c'est mauvais.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Lille
    Inscrit en
    Janvier 2007
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Lille

    Informations forums :
    Inscription : Janvier 2007
    Messages : 17
    Points : 17
    Points
    17
    Par défaut merci mais bon...
    ta solution me semble intéressante, mais on ne peu pas les utiliser dans le cadre de notre projet (sinon prof po content).
    Mais pour en revenir à ma question, ça te semble bien comme logique ?

    encore merci, je ne t'embeterais plus

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Bon ben alors oui, si tu n'as pas le choix.

  9. #9
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par zais_ethael
    Ben non justement, comme je te dis ça va créer un grand nombre de sockets type serveur ce qu'on ne fait jamais (le pire cas est celui de ftp qui en utilise 2, et c'est déja réputé pas pratique à administrer dans les firewall). La meilleure solution serait d'utiliser des threads (je crois vraiment que deux processus ne peuvent pas s'échanger de descripteur de socket, ça doit être comme pour les fichiers).
    Bon, si c'est un petit dossier pour l'école je dis pas mais si c'est pour un vrai programme c'est mauvais.
    Heu... y a méprise là... FTP "offre" deux ports pour permettre de faire du téléchargement, pendant qu'on continue d'envoyer des commandes, mais c'est une usine à gaz...

    Côté client (addresse Ac), l'ouverture d'un socket se fait sur un port Pc différent à chaque connection).
    La connection est demandée sur le serveur (addresse As, port Ps).
    Ce socket devient le canal de transmission côté client.

    Côté serveur, l'acceptation d'un socket va "ouvir" un nouveau socket correspondant au canal de transmssion (côté serveur).
    En IP, un canal de transmission est difini par le T-uple (Ac,Pc,As,Ps)...

    Si un nouveau client arrive (Ae,Pe), un nouveau canal de transmission (socket) sera ouvert , défini par le T-uple (Ae,Pe,As,Ps), et donc qui n'interfera en rien avec le précédent ! A noter que Ae peut être égal à Ac.. c'est pas grave.

    Coté firewall, un seul port à ouvrir, le port du Serveur !

    Ou alors j'ai rien compris au problême

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Pour ftp, c'est bien ce que je dis, un port pour les commandes et un pour les envois/receptions binaires. Bizarrement, certains serveurs ftp proposent d'utiliser plusieurs ports pour les fichiers, ce que je n'ai jamais compris vu qu'un même client ne pourra toujours pas envoyer/recevoir plusieurs fichiers à la foi (ou alors il a un client genre filezilla qui se connecte plusieurs fois au serveur de façon transparente, mais la non plus ça ne nécéssite pas plus de deux ports).
    Sinon, pour le fonctionnement de tcp, c'est tout à fait ça.
    Mais ce n'est pas le mode de fonctionnement que bcaro veut utiliser. La fameuse socket type client qui va être ouverte par le serveur après la tentative de connexion d'un client il ne peut pas la faire passer d'un processus à un autre. Il a donc l'intention d'ouvrir une nouvelle socket serveur sur un nouveau port dans un autre processus qui va à son tour recevoir une connexion d'un client, ouvrir une socket type client ect... La où je n'aime pas, c'est que ça va faire pululer le nombre de sockets type serveur. Et sur le firewall il va falloir ouvrir tous les ports qui sont susceptibles d'être ouverts, en sachant qu'il y en a autant que de clients qu'il peut y avoir en simultané.

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Je crois bien que FTP est plus compliqué que cela.
    Citation Envoyé par FTP
    Déjà, il y a deux modes : Actif et passif.
    • En mode FTP actif, il n'y a qu'une seule connexion du client vers le serveur: La connexion de commande, depuis le client vers le port 21 du serveur.
      Les connexions de fichier se font du serveur vers le client. Le client ouvre un port, l'envoie au serveur avec la commande PORT, et le serveur s'y connecte depuis son propre port 20.
      Problème: Les clients FTP basiques n'offrent aucun moyen de choisir le port qui sera ouvert (FileZilla, lui, le permet). Sans un bon client, il est impossible de configurer son firewall pour laisser passer les connexions sur le port concerné, c'est pourquoi le mode FTP actif échoue très souvent (si le client n'a pas de firewall, ça passe).
    • En mode FTP actif, c'est le contraire: Le client se connecte au serveur pour les transmissions de fichiers. Le client envoie la commande PASV, le serveur ouvre un port et le retourne au client qui s'y connecte.
      Je pense (j'espère) que pratiquement tous les serveurs FTP permettent re choisir le(s) port(s) à ouvrir en mode passif. Si le firewall du serveur est alors bien configuré, ça passera.

    Dans les deux cas, il peut y avoir N connexions de fichier pour une seule connexion de commande.

    Résumé:
    • Si le client et son firewall sont correctement configurés, le mode actif marchera.
    • Si le serveur et son firewall sont correctement configurés, le mode passif marchera.
    En SFTP, tout est encapsulé sur SSH, et il me semble que ce n'est pas du tunneling : seul le port 22 doit être ouvert sur le firewall du serveur.

    zais_ethael :
    Citation Envoyé par zais_ethael
    La fameuse socket type client qui va être ouverte par le serveur après la tentative de connexion d'un client il ne peut pas la faire passer d'un processus à un autre
    Euh... Il me semble que c'est la base de tout serveur-fork, ce qui fait la fierté des systèmes unixoïdes...

  12. #12
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Ben oui je comprends pas non plus.... Il sagit pas de faire 'n' serveurs (un par utilisateur) !

    Si on part du principe "tout TCP".
    Chaque utilisateur a son socket de communication principal.
    Le serveur a un socket d'écoute... et 'n' sockets de communication. 'n' est au minium le nombre d'utilisateurs connectés... En général, cela veut aussi dire 'n' threads coté serveur.
    Après, rien n'empeche l'utilisateur de créer une nouvelle communication pour l'envoi de gros fichiers.
    Le seul port à ouvrir côté firewall c'est le port du socket d'écoute !

    Ou alors j'ai vraiment rien compris à ce que veut faire bcaro !

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    La seule chose qui contredise ce que j'ai dit est ceci:
    Citation Envoyé par Médinoc
    Dans les deux cas, il peut y avoir N connexions de fichier pour une seule connexion de commande.
    Je ne suis pas DU TOUT d'accord.
    Prends un serveur un peu facilement configurable, configure le pour une seule connexion par utilisateur.
    Ouvre deux clients FlashFXP (je cite celui la parcequ'il ne fait pas de multi-connexion comme filezilla), essaie de les connecter tous les deux au serveur (sans se préoccuper des envois de fichier), un seul y parviendra (ce qui est logique).
    Maintenant ferme les flashfxps, lance un filezilla et connecte le au serveur. Envoie un fichier, ça marche. Envoie deux fichiers (filezilla est configuré par défaut pour tenter l'envoi simultané de deux fichiers) ça ne marchera pas. Une connexion FTP = un seul envoi de fichier simultané.

    Citation Envoyé par Médinoc
    Euh... Il me semble que c'est la base de tout serveur-fork, ce qui fait la fierté des systèmes unixoïdes...
    Non, pas pour les IPC. Prends les fichiers par exemple, la commande open() renvoie un pointeur qui pointe une entrée dans la table des descripteurs de fichier, et dans cette table on trouve aussi... le numéro du processus, qui aura forcément tendance à changer si on fait un fork
    Comme je l'ai dit, je ne suis pas sur dans ce cas précis mais je me dis que logiquement c'est impossible. Vu que deux processus ne peuvent en aucun cas ouvrir deux fois le même port (code d'erreur sinon), il me semblerait improbable qu'après un fork puisse aussi facilement contourner une telle interdiction (ou alors il faudrait une gestion bien poussée des sockets au niveau ip et non pas tcp, mais ce serait tiré par les cheveux).

  14. #14
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Citation Envoyé par nicroman
    Ben oui je comprends pas non plus.... Il sagit pas de faire 'n' serveurs (un par utilisateur) !

    Si on part du principe "tout TCP".
    Chaque utilisateur a son socket de communication principal.
    Le serveur a un socket d'écoute... et 'n' sockets de communication. 'n' est au minium le nombre d'utilisateurs connectés... En général, cela veut aussi dire 'n' threads coté serveur.
    Après, rien n'empeche l'utilisateur de créer une nouvelle communication pour l'envoi de gros fichiers.
    Le seul port à ouvrir côté firewall c'est le port du socket d'écoute !

    Ou alors j'ai vraiment rien compris à ce que veut faire bcaro !
    C'est ce que je me tue à te dire.
    bcaro cherche à gérer ça *sans* threads, et le faire avec des processus pose de graves problèmes d'organisation.

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Dans ce cas, tu m'expliquera comment est fait un serveur-fork, si le fork() ne partage pas les objets du kernel.

    De plus, ça marche surtout pour les IPCs : Un tube anonyme est créé avant le fork(), partagé ensuite, c'est le B.A.BA...

    PS: Pour le FTP, il est possible que je me sois avancé... ou non.

  16. #16
    Membre éprouvé
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 064
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 064
    Points : 1 053
    Points
    1 053
    Par défaut
    Bon ben, si tu me dis que plusieurs processus peuvent se partager la même connexion je m'incline, mais j'ai quand même un doute.

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Ben si, aussi bien un processus que plusieurs.
    Attention, je dis bien partager et non dupliquer; C'est comme avec les fonctions dup et dup2 : Ce n'est pas le socket qui est dupliqué, mais seulement le descripteur dessus.

    De plus, c'est ce que fait inetd : Le socket serveur sur lequel une connexion est tentée est passée à la place d'un descripteur standard au nouveau processus: C'est marqué dans l'aide.

    PS: C'est possible aussi sous Windows: DuplicateHandle() fonctionne aussi sur les sockets, j'ai déjà essayé.

Discussions similaires

  1. Réponses: 3
    Dernier message: 18/02/2015, 18h06
  2. Envoyer un gros fichier vers serveur HTTP
    Par Gomoz dans le forum C#
    Réponses: 1
    Dernier message: 22/01/2010, 00h11
  3. Connexion entre serveur et client
    Par ledawa dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 21/05/2008, 18h41
  4. Réponses: 5
    Dernier message: 28/06/2007, 10h17
  5. [Configuration] Je n'arrive pas à envoyer un gros fichier
    Par Alexandrebox dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 2
    Dernier message: 14/03/2007, 09h31

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