# How to send data in a custom format between Python and DRL Studio

**URL:** <https://www.robotexchange.io/t/how-to-send-data-in-a-custom-format-between-python-and-drl-studio/4674>\
**Category:** 💡 How-to\
**Tags:** Python, tcp-ip, Doosan-robot, drl-studio\
**Created:** [September 2, 2026, 12:16am UTC](https://www.robotexchange.io/t/how-to-send-data-in-a-custom-format-between-python-and-drl-studio/4674 "2026-09-02T00:16:02Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![thijs](https://www.robotexchange.io/user_avatar/www.robotexchange.io/thijs/32/4_2.png) [@thijs](https://www.robotexchange.io/u/thijs)\
**Post date:** [September 2, 2026, 12:16am UTC](https://www.robotexchange.io/t/how-to-send-data-in-a-custom-format-between-python-and-drl-studio/4674/1 "2026-09-02T00:16:03Z")

</div>

_Based on contributions by 20129556, Luthfiandra._

Once you have a working socket between a PC and a Doosan robot ([How to connect a Doosan robot to a PC over a TCP socket (DRL Studio and Python)](https://www.robotexchange.io/t/how-to-connect-a-doosan-robot-to-a-pc-over-a-tcp-socket-drl-studio-and-python/4673)), you need a simple, agreed-upon way to encode the data you send — for example a list of numbers from a vision program. This article shows a lightweight text protocol and a threaded server so your PC program keeps running (e.g. keeps processing camera frames) while it answers the robot’s requests.

> ⚠ DRL Studio’s Python is roughly version 3.2, so keep the format itself simple: plain strings with a separator character (like a comma), parsed with basic string methods (`split`, `float`, `int`). Don’t rely on `json`, `pickle`, or other library-heavy encodings for the DRL side.

## What you need

- A working socket connection between the PC and the robot ([How to connect a Doosan robot to a PC over a TCP socket (DRL Studio and Python)](https://www.robotexchange.io/t/how-to-connect-a-doosan-robot-to-a-pc-over-a-tcp-socket-drl-studio-and-python/4673)).
- Python 3 on the PC; DRL Studio on the robot side.

## Steps

### 1. Define the text format

Pick a separator and stick to it. A simple, effective format is a comma-separated string of numbers:

```python
send_data = [10, 147, 382]
data_string = ','.join(map(str, send_data)) # "10,147,382"

```

On the receiving side, split on the same separator and convert back to numbers:

```python
values = data_string.split(",")
x = float(values[0])
y = float(values[1])
z = float(values[2])

```

### 2. Define a request keyword

Rather than pushing data continuously, have the robot ask for a fresh value whenever it’s ready, and have the PC reply only to that request. This avoids the robot processing stale or half-written data.

```python
REQUEST = "[QUESTION]"

```

### 3. Run the PC-side server in a background thread

Run the socket server on its own thread so the rest of your Python program (e.g. a vision loop) is never blocked waiting on the robot.

```python
import socket
import threading

class TcpSocketServer:
    """Threaded TCP server: accepts one client and answers text requests."""

    def __init__ (self, host, port):
        self.host = host
        self.port = port
        self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.server_socket.bind((self.host, self.port))
        self.server_socket.listen(1)
        self.conn = None
        self.address = None

    def start_server(self):
        print(f"Server is running on {self.host}:{self.port}")

    def accept_client(self):
        self.conn, self.address = self.server_socket.accept()
        print(f"Connection from: {self.address}")

    def receive(self, buffer_size=1024):
        data = self.conn.recv(buffer_size)
        return data.decode() if data else None

    def send(self, message):
        self.conn.sendall(message.encode())

    def close(self):
        if self.conn:
            self.conn.close()
        self.server_socket.close()

```

```python
def socket_thread(tcp_server, data_lock, data_container):
    tcp_server.start_server()
    tcp_server.accept_client()

    while True:
        response = tcp_server.receive()
        if response:
            print(f"Received: {response}")
            if response == "[QUESTION]":
                with data_lock:
                    data_string = data_container.get("data")
                tcp_server.send(data_string)
        else:
            print("No response received.")

server_ip = "192.168.137.50" # the PC's own IP address
port = 20002

tcp_server = TcpSocketServer(server_ip, port)

data_lock = threading.Lock()
data_container = {}

threading.Thread(target=socket_thread, args=(tcp_server, data_lock, data_container), daemon=True).start()

while True:
    # Replace this with whatever your program computes each cycle
    # (e.g. object coordinates from a vision pipeline)
    send_data = [10, 147, 382]
    data_string = ','.join(map(str, send_data))

    with data_lock:
        data_container["data"] = data_string

```

The lock protects `data_container` from being read and written at the same time by the two threads. The main loop keeps updating `data_container["data"]` with the latest value; the socket thread only reads it out and sends it when the robot actually asks.

### 4. Request the data from DRL Studio

```python
from DRCF import *

sock = client_socket_open("192.168.137.50", 20002)

while sock:
    msg = "[QUESTION]"
    client_socket_write(sock, msg.encode())

    res, rx_data = client_socket_read(sock)
    rx_msg = rx_data.decode()
    tp_log("{0}".format(rx_msg))

```

The robot repeatedly asks `[QUESTION]`, and each time gets back whatever the PC put in `data_container["data"]` most recently. Parse `rx_msg` with `.split(",")` as shown in step 1 to turn it back into numbers.

## Common mistakes

- **Blocking the vision/data loop.** If the socket server runs on the main thread instead of a background thread, your PC program freezes every time it waits for the robot to connect or ask a question. Always run the server in a `threading.Thread`.
- **Race conditions on shared data.** Always read and write `data_container` inside the `with data_lock:` block — skipping the lock can send half-updated data to the robot.
- **Complex encodings on the robot side.** Remember the Python-3.2 limitation on DRL — don’t design a protocol that needs `json.loads()` or similar on the robot.

## Related

- [How to connect a Doosan robot to a PC over a TCP socket (DRL Studio and Python)](https://www.robotexchange.io/t/how-to-connect-a-doosan-robot-to-a-pc-over-a-tcp-socket-drl-studio-and-python/4673) — setting up the underlying socket connection.
- [How to control a Doosan robot from Python using the API-DRFL wrapper](https://www.robotexchange.io/t/how-to-control-a-doosan-robot-from-python-using-the-api-drfl-wrapper/4675) — an alternative to sockets: control the robot directly from Python without any custom protocol.

* * *

_Rewritten and consolidated (Sept 2026) from the original student how-to’s: [How to send data from Python to the Doosan in your own custom format](https://www.robotexchange.io/t/how-to-send-data-from-python-to-the-doosan-in-your-own-custom-format/3050), [How to integrate TCP/IP communication with python computer vision program and send the data to doosan robot](https://www.robotexchange.io/t/how-to-integrate-tcp-ip-communication-with-python-computer-vision-program-and-send-the-data-to-doosan-robot/3302)._
