tags:

views:

81

answers:

1

I must be missing something in the code. I've rewritten an 'echo server' example to do a bit more when it receives something.

This is how it currently looks:


#!/usr/bin/env python

import select
import socket
import sys
import threading
import time
import Queue

globuser = {}
queue = Queue.Queue()

class Server:
    def __init__(self):
        self.host = ''
        self.port = 2000
        self.backlog = 5
        self.size = 1024
        self.server = None
        self.threads = []

    def open_socket(self):
        try:
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.bind((self.host,self.port))
            self.server.listen(5)
        except socket.error, (value,message):
            if self.server:
                self.server.close()
            print "Could not open socket: " + message
            sys.exit(1)

    def run(self):
        self.open_socket()
        input = [self.server,sys.stdin]
        running = 1
        while running:
            inputready,outputready,exceptready = select.select(input,[],[])

            for s in inputready:

                if s == self.server:
                    # handle the server socket
                    c = Client(self.server.accept(), queue)
                    c.start()
                    self.threads.append(c)

                elif s == sys.stdin:
                    # handle standard input
                    junk = sys.stdin.readline()
                    running = 0

        # close all threads

        self.server.close()
        for c in self.threads:
            c.join()

class Client(threading.Thread):
    initialized=0

    def __init__(self,(client,address), queue):
        threading.Thread.__init__(self)
        self.client = client
        self.address = address
        self.size = 1024
    self.queue = queue
    self.threads = []
        global globuser
        print 'Client thread created!'


    def run(self):
        running = 1
        while running:
            print 'While running client'
            data = self.client.recv(self.size)
            print 'Dit we receive data?'
            if data:
                print 'Data received!'
        print 'Fetching data from socket: ',
        if data[0] == 'I':
            print 'Initializing user: ' + data
            user = {'uid': data[1:6] ,'x': data[6:9], 'y': data[9:12]}
            globuser[user['uid']] = user
            print globuser
            initialized=1
            m=updateClient(user['uid'], queue)
            m.start()
            self.threads.append(m)
            self.client.send('Beginning - Initialized'+';')

        elif data[0] == 'A':
            print 'Client has received previous data: ' + data

        #On deactivation, nothing works.
                self.client.send(data+';')
                #print 'Client Data sent: ' + data
            else:
                print 'Closing'
                self.client.close()
                running = 0

    if self.queue.empty():
        print 'Queue is empty'
    else:
        print 'Queue has information: ',
        data2 = self.queue.get(1, 1)
        isdata2 = 1
        if data2 == 'Exit':
            running = 0
            print 'Client is being closed'
            self.client.close()

    if isdata2 == 1:
        print 'Sending data to client: ' + data2,
        self.client.send(data2)
        self.queue.task_done()
        isdata2 = 0

    time.sleep(1)

class updateClient(threading.Thread):

    def __init__(self,uid, queue):
        threading.Thread.__init__(self)
        self.uid = uid
        self.queue = queue
        global globuser
        print 'updateClient thread started!'

    def run(self):
        running = 20
        test=0
        while running > 0:
            test = test + 1
            self.queue.put('Test Queue Data #' + str(test))
            running = running - 1
            time.sleep(1)

        print 'Updateclient has stopped'



if __name__ == "__main__":
    s = Server()
    s.run() 

This runs fine, although it's kind of silly to keep sending the same data back again along with other data.

In the middle of the code you'll see


        #On deactivation, nothing works.
                self.client.send(data+';')
                #print 'Client Data sent: ' + data

When I DO deactive the self.client.send(data+';') or change it into self.client.send('something else;') it does not work! And the client receives nothing.

Is there something special about the "data" variable? Do I need to format the string in some way?

+2  A: 

Here's a cleaned-up, functional version of your code! I tested it myself, though I didn't write unit tests.

There were some syntax errors and other miscellaneous problems with the original code, so I took some liberties. I'm assuming that the protocol is framed by using ; as a delimiter, since a ; is sent at the end of every message to the client, though no framing was being done in the original code.

from twisted.internet import reactor, protocol, task
from twisted.protocols import basic
from twisted.python import log
import sys

class ServerProtocol(basic.LineOnlyReceiver):
    delimiter = ';'

    def lineReceived(self, line):
        if line.startswith('I'):
            user = dict(uid=line[1:6], x=line[6:9], y=line[9:12])
            self.factory.users[user['uid']] = user
            log.msg(repr(self.factory.users))
            self.startUpdateClient()
            self.sendLine('Beginning - Initialized')
        elif line.startswith('A'):
            self.sendLine(line)
        else:
            self.transport.loseConnection()

    def _updateClient(self):
        if self._running == 0:
            self._looper.stop()
            return
        self._running -= 1
        self._test += 1
        self.sendLine('Test Queue Data #%d' % (self._test,))

    def startUpdateClient(self):
        self._running, self._test = 20, 0
        self._looper = task.LoopingCall(self._updateClient)
        self._looper.start(1, now=False)

class Server(protocol.ServerFactory):
    protocol = ServerProtocol
    def __init__(self):
        self.users = {}

if __name__ == '__main__':
    log.startLogging(sys.stderr)
    reactor.listenTCP(2000, Server())
    reactor.run()
Aaron Gallagher