OVH Cloud OVH Cloud

Pourquoi je n'arrive a rien avec les sockets de python ?

18 réponses
Avatar
aaa
Je teste juste quelque chose avec python, comme recuperer la liste des
forums d'un serveur NNTP.. ca donne ca ...en premier jet :

#################################################################
import socket

serveur='freenews.netfront.net'
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
port=119

s.connect((serveur,port))

print s.recv(1024)

s.send('LIST\n') # theoriquement je demande la liste des forums

chaine=[]
print 'recupere liste de groupe...'
while 1:
data=s.recv(2048) # ca bloque la !!!!!

if not data:
break
chaine.append(data)

s.close()

liste=''.join(chaine) # on groupe les petits bouts
newsgroup=liste.split('\n') # on sépare le tout proprement
print
print 'Ce serveur contient',len(newsgroup),'forums.'

raw_input()
#######################################################

et bien ca ne marche pas ! il recupere bien la liste, mais lors de la
lecture du dernier bloc de 2048 octets, la ligne data=s.recv(2048) ne me
rend pas la main, ca me bloque tout...

Je craque ca fait 2 heures que je suis dessus, est ce que quel'un aurait
une idée ?

Merci beaucoup par avance !

Eric

8 réponses

1 2
Avatar
aaa
In article <4331bbf3$0$15850$, aaa
wrote:



bien possible, mais il m'est impossible de prédeterminer le moment ou
sortir de la boucle, je ne connais pas a l'avance ne nombre d'octets que
je vais lire ...



Ben, tu t'en fous... ce que tu sais c'est qu'il y a x fois 2048 octets


Justement, je ne connais pas le x !


plus y octets (y étant forcément inférieur à 2048) à lire, donc tu
bouclera x fois pour récupérer les x chaines de 2048 octets et il te
resterera à faire un recv(2048) final qui te renverra une chaine faisant
moins de 2048 octets. Je ne vois pas où est le pb (si, effectivement,
recv attend *au plus* le nbre d'octets qui lui est passé en paramètre
comme l'indique ma doc).

Ca doit donner un truc du genre (à la louche) :

resultat <- "";
répéter
data <- s.recv(2048); (1)
si data != "" alors
ajout de data dans result;
sinon
la socket est déconnectée => traiter le pb


Ce test, je ne peux meme pas le faire, car la ligne (1) ne se termine jamais


fin si;
jusqu'à longueur(data) == 2048:
data <- s.recv(2048);
ajout de data dans result;




Avatar
aaa
In article <4331bbf3$0$15850$, aaa
wrote:



bien possible, mais il m'est impossible de prédeterminer le moment ou
sortir de la boucle, je ne connais pas a l'avance ne nombre d'octets que
je vais lire ...



Ca doit donner un truc du genre (à la louche) :

resultat <- "";
répéter
data <- s.recv(2048);
ajouter data à résultat;
jusqu'à longueur(data) < 2048;




imaginons une suite de #, dont je ne peux connaitre a l'avance la longueur :

#############################

ok ?

je vais la lire par "pack" de 4 ok ?

#### #### #### #### #### #### #### #
^
Quand je suis la, comment je sais que
j'en aurai plus qu'un a lire ?
Bon et quand bien meme, quand enfin j'arrive a l'iteration qui tente de
lire le dernier #, la ligne meme qui tente de le faire, ne rend jamais
la main a la ligne suivante ....

Je ne sais pas si me me fait bien comprendre hihihi

enfin, conclusion je comprends quand meme pas pourquoi ca bloque !


Avatar
Eric Jacoboni
In article <4331c350$0$25394$, aaa
wrote:

Ca doit donner un truc du genre (à la louche) :



En fait, j'ai modifié mon post depuis que tu l'as lu, car le premier
algo n'était pas bon...

Essaie le dernier.

--
Jaco


Avatar
aaa
In article <4331bbf3$0$15850$, aaa
wrote:



bien possible, mais il m'est impossible de prédeterminer le moment ou
sortir de la boucle, je ne connais pas a l'avance ne nombre d'octets que
je vais lire ...



Ca doit donner un truc du genre (à la louche) :

resultat <- "";
répéter
data <- s.recv(2048);
ben c'est cette derniere ligne qui bloque, les deux lignes suivantes ne

s'executeront pas...
ajouter data à résultat;
jusqu'à longueur(data) < 2048;




l'algo est bon, mais ca bloque quand meme ...


Avatar
Do Re Mi chel La Si Do
Bonsoir !

J'ai la flemme de lire tous les posts.
Mais j'ai un extrait de code qui fonctionne.

Je le met ci-dessous.

Attention, zoo-logique nécessite utilisateur et mot de passe, ce qui n'est
pas le cas de usenet (par exemple). Dans ce cas, mettre le nom d'utilisateur
et le mot de passe à vide ( = '')

Petite précision, dans le reste du code (non publié ici), j'ai eu beaucoup
de mal pour extraire les payloads des messages en HTML ; et je n'ai toujours
pas résolus tous les problèmes, pour poster en HTML avec payloads (les
librairies Python me rajoutent des caractères parasites, dès que j'utilise
de l'ISO-8859-1 ou 15, et je n'ai guère envie de me contenter de
l'us-ascii...)


@-salutations

Michel Claveau






# -*- coding: cp1252 -*-

# newslist

import nntplib

newsserver='news.zoo-logique.org'
newsport9
newsuser='zoo'
newspasse='entrer'
groupname='programmation.python'

try:
if newsuser<>'' :
ns = nntplib.NNTP(newsserver,newsport,newsuser,newspasse)
else:
ns = nntplib.NNTP(newsserver)
except:
print 'Ne peut se connecter au serveur de news '+newsserver
else:
print 'Le serveur de News est connecté et répond '+ns.getwelcome()
print 'Tentative d accès au groupe '+groupname
try:
group = ns.group(groupname)
except:
print 'Ne peut pas ouvrir le groupe '+groupname
else:
print 'Ok.'
count = group[1] # nb d'articles sur le server
first = group[2] # ID du 1er article disponible
last = group[3] # ID du dernier article disponible
print
print 'Nb articles:',count
print '1er dispo :',first
print 'dernier :',last
ns.quit()
Avatar
Eric Jacoboni
In article <4331c4be$0$1723$, aaa
wrote:


imaginons une suite de #, dont je ne peux connaitre a l'avance la longueur :

#############################

ok ?

je vais la lire par "pack" de 4 ok ?

#### #### #### #### #### #### #### #
^
Quand je suis la, comment je sais que
j'en aurai plus qu'un a lire ?


Tu t'en fous...

Tu lis jusqu'à ce que la dernière lecture te renvoie une longueur
inférieure à 4...

Bon, de toutes façons, ton problème à une solution simple qu'un telnet
met en évidence : la dernière ligne renvoyée par LIST est une ligne
formée d'un seul caractère : '.' (voir le RFC qui va bien). Donc, quand
tu récupères un bloc se terminant par 'n.', c'est que c'est le
dernier...

Il suffit donc d'écrire un truc du genre :

import socket;
serveur = 'news.free.fr'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 119
s.connect((serveur, port))
print s.recv(1024)
result = ""
s.send('LISTrn')
data = s.recv(1024)
while Data.Find("n.") == -1:
result = result + data
data = s.recv(1024)
print data # trace...

print result
s.close()

Le coup du find est un peu lourdingue, mais c'est l'idée, quoi.

--
Jaco

Avatar
Eric Jacoboni
In article <4331c4be$0$1723$, aaa
wrote:


imaginons une suite de #, dont je ne peux connaitre a l'avance la longueur :

#############################

ok ?

je vais la lire par "pack" de 4 ok ?

#### #### #### #### #### #### #### #
^
Quand je suis la, comment je sais que
j'en aurai plus qu'un a lire ?


Tu t'en fous...

Tu lis jusqu'à ce que la dernière lecture te renvoie une longueur
inférieure à 4...

Bon, de toutes façons, ton problème à une solution simple qu'un telnet
met en évidence : la dernière ligne renvoyée par LIST est une ligne
formée d'un seul caractère : '.' (voir le RFC qui va bien). Donc, quand
tu récupères un bloc se terminant par 'n.', c'est que c'est le
dernier...

Il suffit donc d'écrire un truc du genre :

import socket;
serveur = 'news.free.fr'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
port = 119
s.connect((serveur, port))
print s.recv(1024)
result = ""
s.send('LISTrn')
data = s.recv(1024)
while data.find("n.") == -1:
result = result + data
data = s.recv(1024)
print data # trace...

print result
s.close()

Le coup du find est un peu lourdingue, mais c'est l'idée, quoi.

--
Jaco

Avatar
JBB
recv est bloquant si il n'y a rien à lire.
Il faut donc savoir si tu attends encore quelque chose à lire.
Pour ça il y a 3 méthodes en générale:
1) tu connais la taille car envoyée précédemment ( à priori ce n'est pas
le cas dans ce protocole) on trouve ça pour envoyer des fichiers dans
des types MIME dans les mails par exemple.
2) tu attends un chaîne particulière. Par exemple pour un mail dans SMTP
la fin du message c'est rn.rn (ou un truc du genre)
3) tu gère sur timeout (mais c'est pas très joli, surtout si le site
peut être lent)

Dans ton cas je pense que la solution 2 doit marcher.
Est que tu ne reçois pas une ligne vide à la fin ? (ou quelque chose
dans le genre)
Si c'est le cas il suffit de rechercher la séquence correspondante dans
ta chaîne de réception.
1 2