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 :

[Réseau] [socket] create + bind + file descriptor


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut [Réseau] [socket] create + bind + file descriptor
    Bonjour à tous,

    Voilà, sous linux je dispose d'une programme permettant de lire en temps réel des fichier .ts (transport stream) sur une sortie vidéo. Pour l'instant mon programme ne lit que des fichiers sur le disque.
    Je souhaiterais qu'il puisse lire les donnees non pas depuis un fichier .ts mais a partir d'un port sur l'ordinateur (les donnees sont envoyees par le réseau). Pour cela j'utilise un socket, et j'ai quelques soucis avec...

    Mon problème est que la fonction "bind" de mon socket renvoit -1, signifiant que le bind n'a pas fonctionné correctement.

    Voici le code de la fonction responsable de la creation (+bind) de la socket :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    int createSocketTSReader ( void ) {
    	printf ( "creation du socket \n\r" ) ;
     
    	// creation d'un socket
        int sock = socket(PF_INET, SOCK_DGRAM, 0);
        if (sock < 0) {
        	printf ( "Erreur a la creation du socket %d... \n\r", sock ) ;
        	return -1 ;
        }
     
    	// informations sur l'hote distant
        struct sockaddr_in dest = { AF_INET } ; 
       // memset ( &dest, 0, sizeof ( struct sockaddr_in ) ) ;
       // dest.sin_family = AF_INET ;
       // dest.sin_addr.s_addr	= inet_addr ( "127.0.0.1" ) ;
        dest.sin_port = htons ( 1234 ) ;
     
        // association de l'adresse de l'hote avec le socket nouvellement cree
        int res = bind(sock, (struct sockaddr *)&dest, sizeof dest);
        if (res != 0) {
        	printf ( " Erreur au 'bind' du socket %d... \n\r", res ) ;
        	return -2 ;
        }
    	printf ( "Socket cree et correctement associe a l'hote distant \n\r" ) ;
     
    	// reception des donnees en provenances du socket
    	char buf[1500];
    	printf ( "reception des donnees du socket \n\r " ) ;
    	recv(sock, buf, sizeof buf, 0);
     
    	printf ( "fin du socket \n\r" ) ;
    	return sock ;
    }
    J'ai déjà regardé les tutos sur les sockets, mais je ne suis pas un pro et c'est la première fois que j'en implémente. Si quelqu'un a une idée ...

    Egalement, je voudrais savoir comment peut-on considérer le descripteur de fichier renvoyé lors de la création du socket (par la fonction "socket") ? En fait mon code lit des fichiers vidéos .ts a partir d'un argument lors de son appel (ouverture avec la fonction fopen), pourrait-il lire les donnees a partir du descripteur de fichier renvoyé par ce socket ? (avec la fonction fdopen par exemple) ?

    Merci à tous pour votre aide
    D.R.

  2. #2
    Membre émérite Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Par défaut
    Utilise strerror(errno) pour obtenir une chaine décrivant ton problème (juste après ton if(res != 0)).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if(res != 0)
    {
    printf("bind : %d (%d [%s])\n", res, errno, strerror(errno));
    }
    Avec un bon message d'erreur tu pourras peut-être commencer à te dépatouiller.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    Merci pour ta réponse rapide !

    Citation Envoyé par valefor
    Utilise strerror(errno) pour obtenir une chaine décrivant ton problème
    J'ai regardé la signification du dernier message d'erreur grace à ce printf, et il marquait que l'adresse était déjà utilisée. j'ai rajouté précisement l'adresse IP de mon ordinateur et le bind fonctionne parfaitement

    Merci bien à toi valefor !

    Ma question sur le descripteur de fichier renvoyé par la fonction socket () est toujours ouverte

    edit : en rajoutant close ( sock ) à la fin de mon programme, lorsque je le relance je ne parviens pas à le binder à nouveau (l'adresse est déjà utilisée d'aprés le message d'erreur). Comment faut-il faire pour que le bind fonctionne sur la même adresse à chaque appel du programme ?

  4. #4
    Membre émérite Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Par défaut
    Le file descriptor que tu as récupéré est utilisable par read et write de la même manière que pour un fd ouvert avec open. Mais leur comportement peut être différent à cause de différences d'implémentation spécifiques aux fichiers et au réseau. Mais dans un premier temps cela ne devraient pas poser de problème je pense.

    Concernant le bind, j'ai eu pas mal de soucis en essayant des adresses du type 127.0.0.1. Donc comme tu l'as fait, avec l'adresse ip de ta machine c'est bien.

    Le message qui dit quelque chose + "already in use" m'est plutôt apparu avec des socket unix (il fallait alors faire unlink(fd)).

    J'ai pas ce probleme avec les socket inet, et je pense que c'est parceque j'utilise un truc du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    val = 1;
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
    Je crois sans cela ta socket est inutilisable pendant 5 mins.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    Merci pour ta réponse Valefor.

    juste avant de lire ton post, j'ai jeté un coup d'oeil sur la faq où ils expliquaient cette histoire d'adresse already in use.
    Mon socket arrive bien à récupérer les données sur le port que je lui ai spécifié, le bind fonctionne bien et grâce à la ligne de code que tu as conseillé on peut réutiliser une même adresse à chaque lancement du programme sans avoir à attendre quelques minutes ...

    Donc pour ça, ya rien à dire, je suis tout content
    Merci Valefor

    Ma socket reçoit des données sur un port que je lui ai spécifié. J'ai demandé à VLC d'envoyer un fichier .ts en streaming sur ce port, ma socket récupère les infos et les envoit au démultiplexeur / decodeur pour lire la vidéo sur le moniteur.

    Mon soucis est que la vidéo est quasiment illisible : des données reçues le décodeur n'arrive quasiement pas à en décoder...

    Cela vient peut être du descripteur de fichier renvoyé par la socket, que je considère comme étant un fichier Unix pour le décodeur. Quelqu'un-a-t-il une idée ?

  6. #6
    Membre émérite Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Par défaut
    Si tu es sûr que ce qui rentre par le cable réseau est bon, je ne vois pas trop d'où peut venir ton problème.

    Par contre si tu as un doute (vlc encapsule, problème d'endianess, ou autre), tu peux écrire un petit programme "serveur" qui lit ton fichier et qui l'envoi vers ton programme.

    Autre solution plus simple, tu demande à VLC de t'envoyer un ficher foo.txt dans lequel tu met "hello world", et tu affiches ce qui sort de ta chaussette.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    49
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 49
    Par défaut
    Et bien, j'avais pensé à cette idée de petit programme serveur qui recrée un fichier récupéré sur le port sur lequel émet VLC et aprés, essayer de le lire par mon décodeur. Je vais sans doute essayer ça, mais avant j'essaie de passer les données autrement au décodeur qu'avec un descripteur de fichier (celui de la socket).
    Comme je ne suis pas l'auteur du code source du décodeur, il faut que je me plonge dedans pour trouver le buffer d'entrée et le remplir à l'aide de la fonction recv (). C'est une piste que j'étudie depuis hier soir

    En tout cas, tes idées sont très bonnes ...
    Je te tiens au courant !

    Merci bien.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. File descriptor socket
    Par _niko_ dans le forum Réseau
    Réponses: 2
    Dernier message: 07/10/2011, 11h51
  2. Erreur : Bad file descriptor sur socket
    Par TariC dans le forum Réseau
    Réponses: 2
    Dernier message: 22/11/2010, 20h31
  3. pid du process parent du file descriptor du socket
    Par marion5515 dans le forum Réseau
    Réponses: 4
    Dernier message: 27/08/2010, 15h13
  4. Réponses: 0
    Dernier message: 18/11/2007, 20h53
  5. [SOCKET] Fonction bind()
    Par chacal dans le forum Développement
    Réponses: 13
    Dernier message: 19/12/2005, 14h22

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