Client Server programming in python? - python

Here is source code for multithreaed server and client in python.
In the code client and server closes connection after the job is finished.
I want to keep the connections alive and send more data over the same connections to avoid overhead of closing and opening sockets every time.
Following code is from : http://www.devshed.com/c/a/Python/Basic-Threading-in-Python/1/
import pickle
import socket
import threading
# We'll pickle a list of numbers:
someList = [ 1, 2, 7, 9, 0 ]
pickledList = pickle.dumps ( someList )
# Our thread class:
class ClientThread ( threading.Thread ):
# Override Thread's __init__ method to accept the parameters needed:
def __init__ ( self, channel, details ):
self.channel = channel
self.details = details
threading.Thread.__init__ ( self )
def run ( self ):
print 'Received connection:', self.details [ 0 ]
self.channel.send ( pickledList )
for x in xrange ( 10 ):
print self.channel.recv ( 1024 )
self.channel.close()
print 'Closed connection:', self.details [ 0 ]
# Set up the server:
server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
server.bind ( ( '', 2727 ) )
server.listen ( 5 )
# Have the server serve "forever":
while True:
channel, details = server.accept()
ClientThread ( channel, details ).start()
import pickle
import socket
import threading
# Here's our thread:
class ConnectionThread ( threading.Thread ):
def run ( self ):
# Connect to the server:
client = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
client.connect ( ( 'localhost', 2727 ) )
# Retrieve and unpickle the list object:
print pickle.loads ( client.recv ( 1024 ) )
# Send some messages:
for x in xrange ( 10 ):
client.send ( 'Hey. ' + str ( x ) + '\n' )
# Close the connection
client.close()
# Let's spawn a few threads:
for x in xrange ( 5 ):
ConnectionThread().start()

Spawning a new thread for every connection is a really bad design choice.
What happens if you get hit by a lot of connections?
In fact, using threads to wait for network IO is not worth it. Your program gets really complex and you get absolutely no benefit since waiting for network in threads won't make you wait faster. You only lose by using threads in this case.
The following text is from python documentation:
There are only two ways to have a
program on a single processor do “more
than one thing at a time.”
Multi-threaded programming is the
simplest and most popular way to do
it, but there is another very
different technique, that lets you
have nearly all the advantages of
multi-threading, without actually
using multiple threads. It’s really
only practical if your program is
largely I/O bound. If your program is
processor bound, then pre-emptive
scheduled threads are probably what
you really need. Network servers are
rarely processor bound, however.
And if it is a processor bound server case. you could always leave another process/thread to do the processor part. Continuing:
If your operating system supports the
select system call in its I/O library
(and nearly all do), then you can use
it to juggle multiple communication
channels at once; doing other work
while your I/O is taking place in the
“background.” Although this strategy
can seem strange and complex,
especially at first, it is in many
ways easier to understand and control
than multi-threaded programming.
So instead of using threads, use non-blocking input/output: collect the sockets in a list and use an event loop with select.select to know which socket has data to read. Do that in a single thread.
You could choose a python asynchronous networking framework like twisted to do that for you. That will save you a lot of headaches. Twisted's code has been improved for years, and covers some corner cases you'll take time to master.
EDIT: Any existing async IO libraries (like Twisted) are python code. You could have written it yourself, but it has already been written for you. I don't see why you wouldn't use one of those libraries and write your own worst code instead, since you are a beginner. Networing IO is hard to get right.

I'm not sure I understand the question, but don't call close() if you don't want to close the connection...

For an example of a client the keeps a TCP connection open and uses a familiar protocol,
look at the source of the telnetlib module. (sorry, someone else will have to answer your threading questions.)
An example of a server that keeps a TCP connection open is in the source for the SocketServer module (any standard Python installation includes the source).

Related

Why is ZeroMQ poller not receiving messages (python)?

I'm trying to use the ZeroMQ Poller() functionality with two sockets in python:
import zmq
# Prepare our context and sockets
context = zmq.Context()
receiver = context.socket(zmq.DEALER)
receiver.connect("ipc:///tmp/interface-transducer")
subscriber = context.socket(zmq.SUB)
subscriber.bind("ipc:///tmp/fast-service")
subscriber.setsockopt(zmq.SUBSCRIBE, b"10001")
# Initialize poll set
poller = zmq.Poller()
poller.register(receiver, zmq.POLLIN)
poller.register(subscriber, zmq.POLLIN)
# Process messages from both sockets
while True:
try:
socks = dict(poller.poll())
except KeyboardInterrupt:
break
if receiver in socks:
message = receiver.recv()
print("RECEIVER OK\n")
if subscriber in socks:
message = subscriber.recv()
print("SUBSCRIBER OK\n")
And then the server that sends messages as a ROUTER is described as:
def main():
context = zmq.Context()
router = context.socket(zmq.ROUTER)
router.bind("ipc:///tmp/interface-transducer")
while True:
identity = b'electrode-service'
b_identity = identity
router.send_multipart([b_identity, b'[1,2]'])
print("Sent")
time.sleep(1)
if __name__ == "__main__":
main()
But when I run these two processes, it does not work as expected, the poller-script does not print anything. What could be the problem of such implementation?
Q : "What could be the problem of such implementation?"
such implementation is prone to deadlock & fails due to using exclusively the blocking-forms of .poll() & .recv() methods
such implementation is not self-defending enough in cases, where multiple peers get connected into AccessPoints, that implement round-robin incoming/outgoing traffic mappings
such implementation is awfully wrong in standing self-blinded in calling just a single .recv() in cases, where the .send_multipart() is strikingly warning, there will be multi-part message-handling needed
ipc:// Transport Class is prone to hide O/S related user-level code restrictions ( placed by the operating system on the format and length of a pathname and effective user-rights to R/W/X there )
ipc:// Transport Class .connect()-method's use is order-dependent for cases the target-address has not yet been created by O/S services ( a successful .bind() needs to happen first )
last but not least, any next attempt to .bind() onto the same ipc:// Transport Class target will silently destroy your intended ROUTER-access to the messaging/signalling-plane infrastructure & your implementation has spent zero-efforts to self-protect and self-diagnose errors that might silently appear "behind the curtains"
Shouldn't zeromq deal automatically with deadlocks? I tried using the example given in the zeromq guide mspoller If I can't use .poll() and recv() simultaneously, how should I use ZMQ Poller structure? – hao123
No,ZeroMQ zen-of-zero is performance + low-latency focused, so kindly consider all due care for blocking-prevention to be in your own hands (as needed & where needed, the core lib will never do a single more step than needed for the goal of achieving an almost linear scalable performance ).
No, use freely both .poll()- & .recv()-methods, yet complete it so as to fit into a non-blocking fashion - .poll( 0 ) & add active detection + handling of multi-part messages ( again, best in a non-blocking fashion, using zmq.NOBLOCK option flag where appropriate ). Self-blocking gets code out of control.

Threading and tcp/ip connections problems

I'm new in python and threading so please be indifferent. I'm trying to do 2-players game in python. Data are send through tcp/ip protocol (client-server architecture). On server I have three threads. One comunicate with one user, second with second and in third thread I'm getting data which was send by client form two others threads. This data are used to check if game is over. And it's all working good. Problems start now. When the game is over I want to send another data to client. So Thread 3 need to send data to client, but two others threads are still working and they still have connections with clients. Generally I do not know how to do this. I tried to send information through the Queue from third thread to others that they should close theirs connections. It's thread class code:
class myThread(threading.Thread):
def __init__(self, threadID, name, conn, conn2, kto, wartosc,
wybor,kolejkaZadan,gracz1,gracz2):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.conn = conn
self.conn2 = conn2
self.kto = kto
self.wartosc = wartosc
self.wybor = wybor
self.kolejkaZadan = kolejkaZadan
self.gracz1 = gracz1
self.gracz2 = gracz2
def run(self):
if self.wybor == None:
toClient(self.conn,self.conn2,self.kto,self.wartosc,self.gracz1)
else:
while True:
data,kolejkaZwrotna = self.kolejkaZadan.get() // I receive data from two others threads
time.sleep(10)
dataKolejne,kolejkaZwrotna = self.kolejkaZadan.get() // I receive data from two others threads
if data is dataKolejne: // if end
tworzenieXmla(self.gracz1, self.gracz2)
odczytywanieXmla('itemGracza1',gracz1Otrzymane)
plik = open('Marcin.xml', 'rb')
czyZamknacConnection = True
kolejkaZwrotna.put(czyZamknacConnection) // send data to two others threads
while True:
czescXmla = plik.read(10000)
#self.conn2.send(czescXmla)
And It's my send/receiv function which is executed by two other threads:
def toClient(conn, conn2, kto, wartosc,gracz):
wordsBackup = None
kolejkaZwrotna = queue.Queue()
while True:
data = conn.recv(BUFFER_SIZE)
if not data:
break
if kolejkaZwrotna.get() is True://receive form thread 3
conn2.close()
print('closed')
break
if len(data)>7:
print('WARNING', data)
words = str(data.decode()).split()
#print(words[0], words[1])
if kto==1:
conn2.send(data)
if kto==2:
conn2.send(data)
kolejkaZadan.put(words[2],kolejkaZwrotna) // send to thread 3
xmlTablicaDoZapisu(str(int(words[0])),str(int(words[1])),str(int(words[2])),gracz)
Generally there is no error and we can play but there is only one player on each computer so I think server don't send data. I would appreciate any help.
A fix for your current situation would be to change all those connection variables into an array of connections which you could iterate over. You might want to build some container classes which define their behavior since not all clients are the same ( server client, and player clients ). That way you aren't limited by the amount of variables you've declared, and threads available.
Then once a new client connects you simply add it to the array and your iterator will take care of the rest.
This is a common problem with TCP/IP though, in that you always have to have open connections to n clients, which not only takes up resources but since TCP/IP is a queued protocol it could also set the entire game back if any client has a slower connection. In practice your game will always be as laggy as the player with the worst connection.
You have a couple of options.
You can have one thread always open which handles connections. Your supervisor thread. It holds an array of open connections' data and dispenses actions to the other threads. This isn't the best option since you'll quickly encounter Race Conditions such as two threads trying to use the same data.
You can switch over to UDP which will leave your threads wide open since there's no persistent connection. You'd then need to send states to each client, and once they ACK them you can get rid of the data. The majority of games implement UDP now'a'days, even turn based ones.
Beej's guide is probably the most extensive on the internet about UDP/TCP and socket control theory.
http://beej.us/guide/bgnet/output/html/singlepage/bgnet.html
And there's also Gaffer on Games which is a fantastic resource as well.
http://gafferongames.com/networking-for-game-programmers/udp-vs-tcp/

Producing content indefinitely in a separate thread for all connections?

I have a Twisted project which seeks to essentially rebroadcast collected data over TCP in JSON. I essentially have a USB library which I need to subscribe to and synchronously read in a while loop indefinitely like so:
while True:
for line in usbDevice.streamData():
data = MyBrandSpankingNewUSBDeviceData(line)
# parse the data, convert to JSON
output = convertDataToJSON(data)
# broadcast the data
...
The problem, of course, is the .... Essentially, I need to start this process as soon as the server starts and end it when the server ends (Protocol.doStart and Protocol.doStop) and have it constantly running and broadcasting a output to every connected transport.
How can I do this in Twisted? Obviously, I'd need to have the while loop run in its own thread, but how can I "subscribe" clients to listen to output? It's also important that the USB data collection only be running once, as it could seriously mess things up to have it running more than once.
In a nutshell, here's my architecture:
Server has a USB hub which is streaming data all the time. Server is constantly subscribed to this USB hub and is constantly reading data.
Clients will come and go, connecting and disconnecting at will.
We want to send data to all connected clients whenever it is available. How can I do this in Twisted?
One thing you probably want to do is try to extend the common protocol/transport independence. Even though you need a thread with a long-running loop, you can hide this from the protocol. The benefit is the same as usual: the protocol becomes easier to test, and if you ever manage to have a non-threaded implementation of reading the USB events, you can just change the transport without changing the protocol.
from threading import Thread
class USBThingy(Thread):
def __init__(self, reactor, device, protocol):
self._reactor = reactor
self._device = device
self._protocol = protocol
def run(self):
while True:
for line in self._device.streamData():
self._reactor.callFromThread(self._protocol.usbStreamLineReceived, line)
The use of callFromThread is part of what makes this solution usable. It makes sure the usbStreamLineReceived method gets called in the reactor thread rather than in the thread that's reading from the USB device. So from the perspective of that protocol object, there's nothing special going on with respect to threading: it just has its method called once in a while when there's some data to process.
Your protocol then just needs to implement usbStreamLineReceived somehow, and implement your other application-specific logic, like keeping a list of observers:
class SomeUSBProtocol(object):
def __init__(self):
self.observers = []
def usbStreamLineReceived(self, line):
data = MyBrandSpankingNewUSBDeviceData(line)
# broadcast the data
for obs in self.observers[:]:
obs(output)
And then observers can register themselves with an instance of this class and do whatever they want with the data:
class USBObserverThing(Protocol):
def connectionMade(self):
self.factory.usbProto.observers.append(self.emit)
def connectionLost(self):
self.factory.usbProto.observers.remove(self.emit)
def emit(self, output):
# parse the data, convert to JSON
output = convertDataToJSON(data)
self.transport.write(output)
Hook it all together:
usbDevice = ...
usbProto = SomeUSBProtocol()
thingy = USBThingy(reactor, usbDevice, usbProto)
thingy.start()
factory = ServerFactory()
factory.protocol = USBObserverThing
factory.usbProto = usbProto
reactor.listenTCP(12345, factory)
reactor.run()
You can imagine a better observer register/unregister API (like one using actual methods instead of direct access to that list). You could also imagine giving the USBThingy a method for shutting down so SomeUSBProtocol could control when it stops running (so your process will actually be able to exit).

Timeout and high cpu load problems using multiple telnet connection threads in python

I want to connect to multiple telnet hosts using threading in python, but I stumbled about an issue I'm not able to solve.
Using the following code on MAC OS X Lion / Python 2.7
import threading,telnetlib,socket
class ReaderThread(threading.Thread):
def __init__(self, ip, port):
threading.Thread.__init__(self)
self.ip = ip
self.port = port
self.telnet_con = telnetlib.Telnet()
def run(self):
try:
print 'Start %s' % self.ip
self.telnet_con.open(self.ip,self.port,30)
print 'Done %s' % self.ip
except socket.timeout:
print 'Timeout in %s' % self.ip
def join(self):
self.telnet_con.close()
ta = []
t1 = ReaderThread('10.0.1.162',9999)
ta.append(t1)
t2 = ReaderThread('10.0.1.163',9999)
ta.append(t2)
for t in ta:
t.start()
print 'Threads started\n'
In general it works, but either one of the threads (it is not always the same one) takes a long time to connect (about 20 second and sometimes even runs into a timeout). During that awfully long connection time (in an all local network), cpu load also goes up to 100 %.
Even more strange is the fact that if I'm using only one thread in the array it always works flawlessly. So it must have something to do with the use of multiple threads.
I already added hostname entries for all IP addresses to avoid a DNS lookup issue. This didn't make a difference.
Thanks in advance for your help.
Best regards
senexi
Ok, You have overridden join(), and you are not supposed to do that. The main thread calls join() on each thread when the main thread finishes, which is right after the last line in your code. Since your join() method returns before your telnet thread actually exits, Python gets confused and tries to call join() again, and this is what causes the 100% cpu usage. Try to put a 'print' statement in your join() method.
Your implementation of join() tries to close the socket (probably while the other thread is still trying to open a connection), and this might be what causing your telnet threads to never finish.

Python: Listen on two ports

import socket
backlog = 1 #Number of queues
sk_1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sk_2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
local = {"port":1433}
internet = {"port":9999}
sk_1.bind (('', internet["port"]))
sk_1.listen(backlog)
sk_2.bind (('', local["port"]))
sk_2.listen(backlog)
Basically, I have this code. I am trying to listen on two ports: 1433 and 9999. But, this doesn't seems to work.
How can I listen on two ports, within the same python script??
The fancy-pants way to do this if you want to use Python std-lib would be to use SocketServer with the ThreadingMixin -- although the 'select' suggestion is probably the more efficient.
Even though we only define one ThreadedTCPRequestHandler you can easily repurpose it such that each listener has it's own unique handler and it should be fairly trivial to wrap the server/thread creation into a single method if thats the kind of thing you like.
#!/usr/bin/python
import threading
import time
import SocketServer
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
print "%s wrote: " % self.client_address[0]
print self.data
self.request.send(self.data.upper())
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
HOST = ''
PORT_A = 9999
PORT_B = 9876
server_A = ThreadedTCPServer((HOST, PORT_A), ThreadedTCPRequestHandler)
server_B = ThreadedTCPServer((HOST, PORT_B), ThreadedTCPRequestHandler)
server_A_thread = threading.Thread(target=server_A.serve_forever)
server_B_thread = threading.Thread(target=server_B.serve_forever)
server_A_thread.setDaemon(True)
server_B_thread.setDaemon(True)
server_A_thread.start()
server_B_thread.start()
while 1:
time.sleep(1)
The code so far is fine, as far as it goes (except that a backlog of 1 seems unduly strict), the problem of course comes when you try to accept a connection on either listening socket, since accept is normally a blocking call (and "polling" by trying to accept with short timeouts on either socket alternately will burn machine cycles to no good purpose).
select to the rescue!-) select.select (or on the better OSs select.poll or even select.epoll or select.kqueue... but, good old select.select works everywhere!-) will let you know which socket is ready and when, so you can accept appropriately. Along these lines, asyncore and asynchat provide a bit more organization (and third-party framework twisted, of course, adds a lot of such "asynchronous" functionality).
Alternatively, you can devote separate threads to servicing the two listening sockets, but in this case, if the different sockets' functionality needs to affect the same shared data structures, coordination (locking &c) may become ticklish. I would certainly recommend trying the async approach first -- it's actually simpler, as well as offering potential for substantially better performance!-)

Categories