2017-09-17 5 views
0

Bien qu'il soit possible de lire un Gio.Socket en enroulant son fichier descripteur dans Gio.DataInputStream, en utilisant Gio.Socket.receive_from()dans GJS recevoir n'est pas possible parce que commented here:Comment puis-je obtenir l'adresse distante à partir d'un message entrant sur un socket d'écoute UDP?

GJS clonerons arguments de tableau avant de les transmettre le code C qui fera l'appel à Socket.receive_from travail et retournera le nombre d'octets reçus ainsi que la source du paquet. Le contenu du tampon sera inchangé car le tampon effectivement lu est un clone libéré.

Ainsi, les arguments d'entrée sont clonés et les données seront écrites dans le cloné tampon, pas l'instance de buffer effectivement transmis.

Bien que la lecture d'un flux de données ne sont pas un problème, Gio.Socket.receive_from() est la seule façon que je peux trouver pour obtenir l'adresse distante à partir d'un écouteur UDP, puisque Gio.Socket.remote_address sera indéfini. Malheureusement, comme les docs disent pour Gio.Socket.receive():

Pour G_SOCKET_TYPE_DATAGRAM [...] Si le message reçu est trop grand pour tenir dans buffer, les données au-delà de size octets seront mis au rebut, sans aucune indication explicite que cela a eu lieu.

Donc, si je tente quelque chose comme Gio.Socket.receive_from(new Uint8Array(0), null); juste pour obtenir l'adresse, le paquet est avalé, mais si je l'ai lu via le fichier descripteur je ne peux pas dire où le message est venu. Existe-t-il un autre moyen non destructif d'obtenir l'adresse d'arrivée d'un paquet?

+0

Pourquoi le clonage du datagramme vous empêche-t-il d'obtenir sa source? – EJP

+0

Désolé, le commentaire que j'ai cité n'est pas tout à fait clair. Obtenir l'adresse est possible avec 'Gio.Source.receive_from (buffer, cancellable)' (dans GJS ceci retourne un tableau de '[size, address]'), mais parce que GJS clone les arguments passés dans le 'buffer' n'aura aucun les données écrites à lui. Passer ainsi un 'Uint8Array (4096)' entraînera le remplissage de 'buffer' avec 4k octets nuls, puisque les données sont écrites dans l'argument cloné, pas dans l'original. –

+0

J'ai clarifié quelque peu ma question. –

Répondre

1

Étant donné que vous utilisez un socket de datagramme, il devrait être possible d'utiliser Gio.Socket.receive_message() et de lui passer le drapeau Gio.SocketMsgFlags.PEEK. Ce n'est pas possible pour une socket basée sur le flux, mais vous ne voulez pas l'adresse de l'expéditeur pour chaque lecture que vous faites dans ce cas.

Si vous voulez améliorer les performances, vous pouvez utiliser Gio.Socket.receive_messages(), même si je ne suis pas sûr que ce soit complètement introspectable pour le moment.

+0

Excellent, ça le fait! J'avais presque perdu espoir sur celui-ci. –