Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

10 réponses

1 2
Avatar
Eric Jacoboni
In article <4331ab13$0$15843$, aaa
wrote:

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


s.send('LISTn') # theoriquement je demande la liste des forums


Moi, déjà, je mettrai un rn à la place du n car je crois que c'est ce
que le protocole attend (à vérifier).

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


J'ai pas la doc sous la main, mais il faudrait vérifier que si ta
méthode de réception attend exactement 2048 octets ou au maximum 2048
octets... Par ailleurs, tu as vérifié par un telnet ce que tu obtiens
réellement de la part du serveur ?

Sinon, je sais bien que ça ne répond pas à ta question, mais sais-tu
qu'il existe un module Python très bien fait pour communiquer avec les
serveurs NNTP ?

--
Jaco

Avatar
Bertrand B
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)
port9

s.connect((serveur,port))

print s.recv(1024)

s.send('LISTn') # 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 aurai t
une idée ?

Merci beaucoup par avance !

Eric
Bonjour,


C'est normal par défaut un lecture sur une socketest bloquante, l'appel
a recv ne rendar la main qu'après avoir lu 2048 octets.

je vous conseils de jeter un oeil à setblocking

Il vous faudra bien sur traiter l'exception.

Avatar
aaa
en fait, pour telnet, oui. Je teste mon script en parallele. Et ca se
passe bien (sous telnet).
Ce que je ne comprends pas c'est que c'est uniquement la sequence qui
recupere la liste qui bloque.

Theoriquement la comme .recv(n) recupere ce qu'elle peut jusqu'a
concurrence de n octet(s), donc le probleme ne devrait pas se situer là.

J'ai partiellement resolu mon probleme en utilisant un timeout qui me
leve un exception -> ce que me permet de reprendre la main. Mais enfin
cette solution ne me plait pas, je voudrais comprendre le pourquoi du
comment.

En ce qui concerne le module NNTP, je sais que ca marche très bien, mais
je voudrais tout simplement avoir plus de controle sur ce que je fais.

Dans tout les cas, merci de m'avoir repondu.

Eric
Avatar
aaa
je vois ce que vous voulez dire, mais alors comment cela se fait t'il
que ca ne bloque pas a ce niveau la:

############""
s.connect((serveur,port))

print s.recv(1024)
######

lors de la connection, le serveur ne me renvois pas 1024 octets, mais
beaucoup moins ....

Je vais faire un test, je vais changer s.recv(1024) en s.recv(1), pour
voir ...

Merci beaucoup
Avatar
Eric Jacoboni
In article <4331b848$0$1728$, aaa
wrote:

Theoriquement la comme .recv(n) recupere ce qu'elle peut jusqu'a
concurrence de n octet(s), donc le probleme ne devrait pas se situer là.


Effectivement, je viens de retrouver mon bouquin... recv reçoit
*jusqu'à* le nombre d'octets indiqué, ce qui signifie qu'elle peut donc
en lire moins. En conséquence, si la dernière lecture fait moins de 2048
octets, ça devrait passer.

Par contre, je lis également dans la doc que recv renvoie ce qui a été
lu, et ne renvoie la chaine vide que si la socket est déconnectée...

Si c'est le cas, ta boucle ne va pas puisque tu attends que la chaine
renvoyée soit vide... donc que la socket soit déconnectée. Essaie en
modifiant le test : genre, tant qu'on lit 2048 octets, on boucle. Après
la boucle, il restera un recv à faire pour lire les octets finaux.

--
Jaco

Avatar
aaa
bon, je viens de tester, ca bloque aussi !!!!

Donc, là, je ne comprends vraiment pas ce qui se passe ...

j'ai essayé avec plusieurs serveurs, c'est identique.
Avatar
aaa
In article <4331b848$0$1728$, aaa
wrote:


Theoriquement la comme .recv(n) recupere ce qu'elle peut jusqu'a
concurrence de n octet(s), donc le probleme ne devrait pas se situer là.



Effectivement, je viens de retrouver mon bouquin... recv reçoit
*jusqu'à* le nombre d'octets indiqué, ce qui signifie qu'elle peut donc
en lire moins. En conséquence, si la dernière lecture fait moins de 2048
octets, ça devrait passer.

Par contre, je lis également dans la doc que recv renvoie ce qui a été
lu, et ne renvoie la chaine vide que si la socket est déconnectée...

Si c'est le cas, ta boucle ne va pas puisque tu attends que la chaine
renvoyée soit vide... donc que la socket soit déconnectée. Essaie en
modifiant le test : genre, tant qu'on lit 2048 octets, on boucle. Après
la boucle, il restera un recv à faire pour lire les octets finaux.



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 ...

Mais je vais quand meme y reflechir ...

Merci encore une fois :-)

Eric


Avatar
Eric Jacoboni
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
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);
si data != "" alors
ajout de data dans result;
sinon
la socket est déconnectée => traiter le pb
fin si;
jusqu'à longueur(data) == 2048:
data <- s.recv(2048);
ajout de data dans result;

--
Jaco

Avatar
Eric Jacoboni
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
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 <- "";
boucle sans fin
data <- s.recv(2048);
si longueur(data) != 2048 alors
sortir de la boucle
sinon
ajouter data à résultat;
fin si;
fin boucle;
data <- s.recv(2048);
ajout de data dans result;

--
Jaco

Avatar
Eric Jacoboni
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;

--
Jaco

1 2