7
votes

Sockets Python non bloquants

J'aimerais écrire une petite application de serveur Bluetooth à mon téléphone Nokia à PYS60. Il doit également être en mesure d'envoyer une réponse à la demande du client et de pouvoir appuyer également les données sur le client.

Option 1 : Si j'utilise socket.recv (1024) , le programme attend jusqu'à ce que quelque chose soit reçu, le serveur ne peut donc pas appuyer sur les données sur le client. Le python pour la mise en oeuvre S60 manque à la méthode socket.settimeout () , donc je ne pouvais donc pas écrire un code non bloqué approprié.

Oprion 2 : L'approche socket.makefile () était bonne, mais ne pouvait pas le faire fonctionner. Lorsque j'ai remplacé le conn.recv (1024) sur fd = socket.makefile () fd.readline () , il n'a pas lu quelque chose.

option 3 : Regardé dans la fonction SELECT () , mais n'avait pas de chance avec elle. Quand j'ai changé le conn.recv () vers le r, w, e = sélectionnez.select ([Conn], [], [], []) Comme il a été suggéré le Le client ne se connecte même pas. Il se bloque à "attendre le client ...". Etrange ...

Je sais qu'il existe de jolies implémentations de serveurs et d'API asynchrones aussi, mais je n'ai besoin que d'un truc vraiment basique ici. Merci d'avance!

Voici ce que j'ai: xxx

Il bloque évidemment, de sorte que "certaines autres données" n'est jamais envoyée, mais c'est le meilleur J'ai jusqu'à présent. Au moins, je peux envoyer quelque chose en réponse au client.


0 commentaires

3 Réponses :


1
votes

Voici un exemple simple basé sur un Echo Server

#!/usr/bin/python                                                                                                                                                                                                                                                    

import socket
import select

server = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
server.bind( ('localhost', 12556) )
server.listen( 5 )

toread = [server]

running = 1

# we will shut down when all clients disconenct                                                                                                                                                                                                                      
while running:

    rready,wready,err = select.select( toread, [], [] )
    for s in rready:
        if s == server:
            # accepting the socket, which the OS passes off to another                                                                                                                                                                                               
            # socket so we can go back to selecting.  We'll append this                                                                                                                                                                                              
            # new socket to the read list we select on next pass                                                                                                                                                                                                     

            client, address = server.accept()
            toread.append( client )  # select on this socket next time                                                                                                                                                                                               
        else:
            # Not the server's socket, so we'll read                                                                                                                                                                                                                 
            data = s.recv( 1024 )
            if data:
                print "Received %s" % ( data  )
            else:
                print "Client disconnected"
                s.close()

                # remove socket so we don't watch an invalid 
                # descriptor, decrement client count                                                                                                                                                                      
                toread.remove( s )
                running = len(toread) - 1

# clean up                                                                                                                                                                                                                                                           
server.close()


1 commentaires

Merci, mais ce n'est pas ce dont j'ai besoin. Je dois connecter un seul client (via Bluetooth), il ne provoque donc aucun problème de bloquer la prise jusqu'à ce que le client soit connecté. Une fois la connexion initiée, le serveur doit envoyer et recevoir des données. Je ne comprends pas, pourquoi le RECV () bloque la prise de mode .SeSetBlocking (0). La sélection semble bloquer également.



0
votes

Voici une implémentation du serveur d'épollal (non bloquant)

http://pastebin.com/vp6kptww (Même chose que ci-dessous, vous avez senti que cela pourrait être plus facile à copier)

Utiliser python epollserver.py pour démarrer le serveur.

Testez-le en utilisant wget localhost: 8888 xxx


0 commentaires

2
votes

a trouvé la solution enfin!

La fonction Select ne fonctionnait pas avec le module BTSocket des nouveaux ports PYS60. Quelqu'un a écrit un nouveau_btsocket (disponible ici ) avec une fonction de sélection de travail.


0 commentaires