Bidirectional Networking

Emanuele D'Arrigo manu3d at gmail.com
Sat Dec 13 16:03:17 CET 2008


On Dec 12, 9:04 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
wrote:
> If you're using 2.5 or older, override serve_forever:
>
>      def serve_forever(self):
>          while not getattr(self, 'quit', False):
>              self.handle_request()
>
> and set the server 'quit' attribute to True in response to some command
>  from the client.

Ok, I've tried this method and it would work if I wanted to shut down
the server from the remote client. But if I want the server to shut
down from the server itself upon some condition it doesn't work
because the while statement is evaluated again only after there has
been a request. If requests are infrequent or have ceased the
self.handle_request() is never invoked and both the loop and the
thread that contains it hang. I wasn't able to set a timeout upon
which the handle_request() method returns. I'm not sure why. But I was
able to make the original serve_forever() work.

The problem was that in my code I used:

asyncServer.daemon = True

but somehow that doesn't work. I then tried:

asyncServer.setDaemon(True)

and that does work: when the asyncClient thread ends the only thread
left running is the asyncServer, but as it is a daemon thread and
there are no non-daemon threads left, the application exits regularly.
So, below there's an updated version of my code that works as
intended.

Thanks for your help!

Manu


-------------------------
To use the following code, cut&paste into two separate *.py files and
invert the port numbers in one file. Then, start them in two separate
shells.
-------------------------

import SocketServer
import socket
import threading
import random
from time import sleep

## Network request handler
class MyTCPHandler(SocketServer.StreamRequestHandler):

    def handle(self):
        self.data = self.rfile.readline().strip()
        print "-> RECV: " + self.data + " - Sent by:" +
self.client_address[0]

## Server Thread
class ServerThread(threading.Thread):
    def __init__(self, localServer):
        threading.Thread.__init__(self)
        self.server = SocketServer.TCPServer(localServer,
MyTCPHandler)

    def run(self):
        self.server.serve_forever()

## Client Thread
class ClientThread(threading.Thread):

    def __init__(self, remoteServer):
        threading.Thread.__init__(self)
        self.remoteServer = remoteServer

    def run(self):
        cycle = 0
        while cycle < 1000:

            chance = random.random()
            if(chance < 0.01):

                randomNumber = int(random.random() * 1000)
                message = str(randomNumber) + " from remote cycle " +
str(cycle)

                try:
                    sock = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
                    sock.connect(self.remoteServer)
                    sock.send(message + "\n")
                    sock.close()
                    print("SENT ->: "+str(randomNumber)+ " by local
cycle "+str(cycle))
                except:
                    print("Failed to send number on cycle "+str
(cycle))

            cycle += 1
            sleep(0.01)

## Simulating local/remote servers with different ports
localServer = ("localhost", 9999)
remoteServer = ("localhost", 10000)

serverThread = ServerThread(localServer)
serverThread.setDaemon(True)
serverThread.start()

clientThread = ClientThread(remoteServer)
clientThread.start()


---------------------------





More information about the Python-list mailing list