prosseek
prosseek

Reputation: 190659

Send multiple messages to server from twisted client

I'm trying to build a client/server system that clients send messages to server. Server does nothing more than printing out what clients send.

from twisted.internet import protocol, reactor

class Echo(protocol.Protocol):
    def dataReceived(self, data):
        print data
        self.transport.write(data)

class EchoFactory(protocol.Factory):
    def buildProtocol(self, addr):
        return Echo()

reactor.listenTCP(8000, EchoFactory())
reactor.run()

The issue is that when I tried to send multiple message from client with this code, the client raises an error after the first connection and send.

from twisted.internet import reactor, protocol
import time

class EchoClient(protocol.Protocol):
   def __init__(self, message):
       self.message = message

   def connectionMade(self):
       self.transport.write(self.message)

   def dataReceived(self, data):
       print "Server said:", data
       self.transport.loseConnection()

class EchoFactory(protocol.ClientFactory):
   def __init__(self, message):
       self.message = message

   def buildProtocol(self, addr):
       return EchoClient(self.message)

   def clientConnectionFailed(self, connector, reason):
       print "Connection failed."
       reactor.stop()

   def clientConnectionLost(self, connector, reason):
       print "Connection lost."
       reactor.stop()

def sendMessage(message):
    reactor.connectTCP("localhost", 8000, EchoFactory(message))
    reactor.run()

if __name__ == "__main__":
    while True:
        r = raw_input(">")
        if r == 'q' or len(r) == 0: break
        sendMessage(r)

What might be wrong? this is the error message.

>a
Server said: a
Connection lost.
>b
Traceback (most recent call last):
  File "echoclient.py", line 38, in <module>
    sendMessage(r)
  File "echoclient.py", line 32, in sendMessage
    reactor.run()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/base.py", line 1168, in run
    self.startRunning(installSignalHandlers=installSignalHandlers)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/base.py", line 1148, in startRunning
    ReactorBase.startRunning(self)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/base.py", line 680, in startRunning
    raise error.ReactorNotRestartable()
twisted.internet.error.ReactorNotRestartable

Upvotes: 2

Views: 2229

Answers (3)

user823743
user823743

Reputation: 2172

Although this question is old and has two irrelevant answers, I would like to answer it for the people who are eager to know. The problem is that in your server code in the dataReceived method you have self.transport.write(data) (which sends every message that it receives to the client), and at the same time in your client code, again in the dataReceived method you have the command self.transport.loseConnection() (which looses the connection to the server as soon as a message comes in). So, if you remove any of these lines you should be fine. In the current setting the first message sent from client will be sent back to the client and that will cause a connection disconnect.

Also, you are calling reactor.run () at each attempt for sending a message. Reactor.run should be called only once preferably in the main function.

Upvotes: 2

prosseek
prosseek

Reputation: 190659

For my own purposes, using socket to send messages to server works fine.

import socket
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('localhost', 8000))
while True:
    a = raw_input("> ")
    if a == 'q' or len(a) == 0: 
        client_socket.close()
        break
    else:
        client_socket.send(a)

Upvotes: -1

Jean-Paul Calderone
Jean-Paul Calderone

Reputation: 48315

The reactor is not restartable.

Upvotes: 0

Related Questions