Python Threaded TCP Socket Server Example

I created this repo recently and thought some of you might find it useful for your projects. There are a lot of ways to create a stand-alone tcp socket server in python and a shitload of examples out there so it can be a bit difficult to figure out which is the best one to use or start from.

I use this particular example pretty often when we need to communicate to TD from a Flask app or really any python app/code that would be risky (or impossible) to run directly from TD.

If you were to send a message to it from TD you could use the TCP DAT and do something like this from a Text DAT:

from datetime import datetime
import json

msg = {
	'cmd': 'test',
	'data': [str(],

msg = json.dumps(msg)


And then parse the incoming message in the callback script for the TCP DAT like so:

import json

def onReceive(dat, rowIndex, message, bytes, peer):
	myjson = json.loads(message)
	cmd = myjson['cmd']
	data = myjson['data']
	print(cmd, data)

One interesting thing I have noticed is that TD tends to add an extra byte on the end of the message (0x00). I’m a little unclear about why this would happen but I added this line in the server to help deal with that issue:

data = loads(data.rstrip('\0'))

This example could be enhanced with the addition of a user provided callback function for the received client messages but I decided that it would be better not to overly complicate things. Later on I may add a different version for that.


1 Like

Thanks Matthewwatcher, simple and easy to read code.
I d be interesting in seeing the user provided callback functions example if that’s possible. Wonder a few time how to structure those callbacks.


@oliviano something like this

from datetime import datetime
from json import loads, dumps
from pprint import pprint
import socket
from threading import Thread

class ThreadedServer(Thread):
    def __init__(self, host, port, timeout=60, callback=None, debug=False): = host
        self.port = port
        self.timeout = timeout
        self.callback = callback
        self.debug = debug

    # run by the Thread object
    def run(self):
        if self.debug:
            print('SERVER Starting...', '\n')


    def listen(self):
        # create an instance of socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        # bind the socket to its host and port
        self.sock.bind((, self.port))
        if self.debug:
            print('SERVER Socket Bound',, self.port, '\n')

        # start listening for a client
        if self.debug:
            print('SERVER Listening...', '\n')
        while True:
            # get the client object and address
            client, address = self.sock.accept()

            # set a timeout

            if self.debug:
                print('CLIENT Connected:', client, '\n')

            # start a thread to listen to the client
                args=(client, address, self.callback)

            # send the client a connection message
            # res = {
            #     'cmd': 'connected',
            # }
            # response = dumps(res)
            # client.send(response.encode('utf-8'))

    def listenToClient(self, client, address, callback):
        # set a buffer size ( could be 2048 or 4096 / power of 2 )
        size = 1024
        while True:
                # try to receive data from the client
                data = client.recv(size).decode('utf-8')
                if data:
                    data = loads(data.rstrip('\0'))
                    if self.debug:
                        print('CLIENT Data Received', client)
                        pprint(data, width=1)

                    if callback is not None:
                        callback(client, address, data)

                    raise error('Client disconnected')

                if self.debug:
                    print('CLIENT Disconnected:', client, '\n')
                return False

def some_callback(client, address, data):
    print('data received', data)
    # send a response back to the client

    res = {
        'cmd': data['cmd'],
        'data': data['data']
    response = dumps(res)

if __name__ == "__main__":
    ThreadedServer('', 8008, timeout=86400, callback=some_callback, debug=True).start()