2011-10-04 2 views
1

Je travaille donc sur un framework Python IRC et j'utilise le module socket de Python. Ai-je envie d'utiliser Twisted? Non, pas vraiment.Problèmes avec le module de socket Python

Quoi qu'il en soit, j'ai une boucle infinie lire et traiter des données de socket.recv(xxxx), où xxxx est vraiment hors de propos dans cette situation. Je divise les données reçues en messages en utilisant str.split("\r\n") et les traite un par un.

Mon problème est que je dois définir une «taille de lecture» spécifique dans socket.recv() pour définir la quantité de données à lire à partir du socket. Quand je reçois une rafale de données (par exemple, lorsque je me connecte au serveur IRC et que je reçois MOTD.etc), il y a toujours un message qui couvre deux "lectures" de la socket (ie une partie de la ligne est lue en socket.recv() et le reste est lu dans la prochaine itération de la boucle infinie).

Je ne peux pas traiter les messages à moitié reçus, et je ne suis pas sûr qu'il existe même un moyen de les détecter. Dans une situation idéale, je recevrais tout ce qui est dans le tampon, mais il ne semble pas que socket fournit une méthode pour le faire.

Une aide?

+0

Pourquoi réinventer la roue? Il y a déjà un tas de solutions pour faire cela, dont Twisted est la plus polyvalente. – jathanism

+0

Pourquoi ne voulez-vous pas utiliser Twisted? – dicato

Répondre

4

Vous devriez vraiment utiliser select ou poll, par ex. via asyncore ou select, ou tordu (que vous préférez ne pas).

En lisant à partir d'une socket, vous ne savez jamais combien vous recevrez à chaque lecture. Vous pouvez recevoir plusieurs messages en une fois, ou faire diviser un message en plusieurs lectures. Vous devriez toujours collecter les données dans un tampon jusqu'à ce que vous puissiez l'utiliser, puis supprimer les données que vous avez utilisées du tampon (mais laisser des données que vous n'avez pas encore utilisées).

Puisque vous savez que votre entrée rend la ligne de détection par ligne, votre boucle de réception peut ressembler à:

  • while true:
    • ajouter de nouvelles données tampon
    • Rechercher des EOL, processus et supprimer toutes les lignes complètes
+0

Je fais une chose similaire; Je divise l'entrée en lignes et ajoute les lignes à un tampon d'entrée. Je suppose que je pourrais utiliser l'existence d'une nouvelle ligne pour déterminer si les données reçues sont 'complètes'. –

+0

Oui, dans votre cas, les retours à la ligne déterminent la fin d'un message – orip

0

Les sockets en mode continu (par exemple, TCP) ne garantissent jamais que vous recevrez des messages dans un format parfaitement cadré. Si vous recevez des lignes d'entrée partielles - qui vont inévitablement arriver - vous devez vous tenir sur la ligne partielle jusqu'à ce que le reste de la ligne apparaisse. L'utilisation de Twisted vous fera gagner beaucoup de temps. Mieux encore, vous pouvez envisager d'utiliser un framework IRC existant - il y en a déjà plusieurs disponibles.

Questions connexes