6
votes

Socket-> Recv () vs.>?

J'essaie de travailler à travers un petit projet d'apprentissage Perl qui nécessite la lecture de 4 entiers non signés à partir d'une prise. Je ne pouvais pas obtenir plus d'une lecture entière et, après avoir creusé, j'ai trouvé une solution. Mais j'ai besoin de comprendre ce que je n'ai pas fait de droite (et j'ai traversé deux livres Perl, perdocs, etc. en vain.)

Exemple 1: Voici le code de la solution réussi ( Original ), suppose que le socket Connect abresse Pour les deux ci-dessous: xxx

exemple 2: J'ai essayé ceci ci-dessous. Si j'imprime l'entrée avant le déballage, je reçois un entier: xxx

Questions spécifiques:

  1. Dans l'exemple 1, quel est le diable "$ /"? Et comment ça "change" <>, que je pensais lire stdin?
  2. Dans l'exemple 2, y a-t-il une raison pour laquelle mon RECV () ne prend pas plus d'un entier hors de la prise? Ma compréhension (par perdoc) est que le paramètre "Taille" par défaut des "octets" et les entiers sont 4 octets?

    Une aide, des pointeurs, etc. est apprécié. BTW, le "projet d'apprentissage" est surtheware.org - des trucs assez cool.


1 commentaires

Pour obtenir le matériel de documentation simple hors de la manière suivante: Perlvar $ / ; <> est juste un nom différent pour readline


3 Réponses :


2
votes

comme pour 1)

Eh bien, <> prend tout fichier de fichiers, y compris les sockets. C'est une convention que vous pouvez le laisser vide, auquel cas une sorte de comportement par défaut sain d'esprit est supposé. Voir Perldoc Perlop (recherche de <> à l'intérieur).

et une variable spéciale $ / est un séparateur d'enregistrement et il est par défaut sur "\ n". Vous pouvez le devenir et lire le fichier entier à la fois (appelé TLURPING). Voir perldoc perlvar Pour plus (le cas \ numéro est également là).


1 commentaires

Cela a fonctionné pour moi, bien que j'ai utilisé tous les commentaires. Je n'ai jamais pu être lu / readline / RECV pour travailler. Mais maintenant que je comprenne à utiliser <> et $ /, je suis à l'aise d'allumer. Merci pour l'aide.



5
votes

est votre socket TCP ou UDP?

RECV est une routine de niveau inférieur à celle de <> / readline . Il mesure plus ou moins directement dans le recv (2) appel système. Si les données de socket arrivent sous forme de 4 paquets 4 octets, RECV reviendra immédiatement une fois qu'il voit le premier paquet, même s'il a été fourni un tampon plus grand. Si tous les 4 paquets arrivent avant le premier appel sur RECV () , alors que vous obtenez toutes les données ou qu'une seule pièce dépend probablement de ce que c'est TCP ou UDP.

Si vous utilisez TCP, il est possible que les paquets soient fragmentés en vol. Il est peu probable qu'il ait lieu avec des charges utiles de 16 octets, mais la meilleure pratique ne serait pas de supposer que 16 octets de données apparaîtront à la fois même si vous connaissez le serveur l'a immédiatement envoyé à la fois. Les applications réseau sont généralement censées tamponner les données entrantes ou, vous pouvez le faire Perl pour vous en spécifiant des enregistrements de 16 octets avec $ / = \ 16 . .

Une autre possibilité, que je trouve plus naturelle que <> pour ce type d'utilisation d'E / S, est d'utiliser le lire ou sysdread Fonctions (ou les équivalents OO, qui sont définis dans le io :: socket Superclass io :: poignée ). Ceux qui prennent un argument de longueur, mais comme auparavant, vous ne devriez pas supposer que tout le tampon sera rempli à la fois.


0 commentaires

1
votes

lire et readline (alias <> ) attendez que la quantité demandée de caractères soit disponible avant de revenir. Il ne renverra que moins de caractères en cas d'erreur ou d'EOF, auquel cas la prochaine lecture renvoie une erreur ou EOF.

sysdread retourne dès que certains caractères sont disponibles, même s'il y a moins de la quantité demandée.

Basé sur ce que vous dites, RECV est comme sysdread . Si vous voulez 16 caractères, vous devrez vous mettre en boucle jusqu'à ce que vous disposiez de 16 caractères ou d'utiliser lisez ou readline .


0 commentaires