Based on contributions by Luthfiandra.
Use this when several clients — for example a laptop and a robot controller — need to talk to the same Python server over the network at the same time, and messages from one client should be forwarded to the others.
What you need
- Python 3 on the machine that will act as the server (a lab PC works well).
- All clients on the same network/IP range as the server.
- The server’s IP address and a free port (e.g.
20002).
Fill in your own server IP address and port below.
192.168.123.100is only an example — check the server’s actual address (e.g. withipconfigon Windows orip addron Linux).
Steps
1. Write the server
The server listens for incoming connections, starts a new thread per client so it can serve everyone at once, and forwards any message it receives to all other connected clients.
import socket
import threading
# Server address and port - replace with your own
SERVER_ADDRESS = ("192.168.123.100", 20002)
# Create a TCP/IP socket
server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_sock.bind(SERVER_ADDRESS)
server_sock.listen(5) # queue up to 5 pending connections
print(f"Server is listening on {SERVER_ADDRESS}")
clients = [] # keeps track of connected clients
def handle_client(connection, client_address):
"""Handle one client connection in its own thread."""
print(f"Connection from {client_address}")
clients.append(connection)
try:
while True:
data = connection.recv(1024)
if not data:
print(f"No data from {client_address}. Closing connection.")
break
print(f"Received from {client_address}: {data.decode()}")
forward_message(data, connection)
except Exception as e:
print(f"Error with {client_address}: {e}")
finally:
clients.remove(connection)
connection.close()
print(f"Connection with {client_address} closed.")
def forward_message(message, sender_connection):
"""Forward a message to every connected client except the sender."""
for client in clients:
if client != sender_connection:
try:
client.sendall(message)
except Exception as e:
print(f"Failed to send message to {client}: {e}")
while True:
connection, client_address = server_sock.accept()
client_thread = threading.Thread(target=handle_client, args=(connection, client_address))
client_thread.start()
This creates a server that can handle up to 5 pending connections and relays any message it receives to all other clients. If you only want to talk to one specific client, filter on client_address instead of broadcasting to the whole list.
2. Write a client (PC or laptop)
Make sure the client’s IP address is in the same range as the server’s (in this example,
192.168.123.xxx). Check your own IP withipconfig(Windows) orip addr/ifconfig(Linux/macOS).
import socket
import threading
SERVER_ADDRESS = ("192.168.123.100", 20002) # must match the server
def receive_messages(sock):
"""Continuously print any message received from the server."""
while True:
try:
message = sock.recv(1024)
if not message:
print("Disconnected from the server.")
break
print(f"Received: {message.decode()}")
except Exception as e:
print(f"Error receiving message: {e}")
break
def main():
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client_sock.connect(SERVER_ADDRESS)
print(f"Connected to server at {SERVER_ADDRESS}")
threading.Thread(target=receive_messages, args=(client_sock,), daemon=True).start()
while True:
message = input("Enter message to send (or 'exit' to quit): ")
if message.lower() == "exit":
print("Exiting...")
break
client_sock.sendall(message.encode())
except Exception as e:
print(f"Error: {e}")
finally:
client_sock.close()
print("Connection closed.")
if __name__ == "__main__":
main()
3. Connect a robot as a client
The server code above works the same way regardless of what connects to it — a laptop, a PLC, or a robot controller that opens a TCP socket. For robot-specific client code, see:
- How to send data in a custom format between Python and DRL Studio — sending data from Python to a Doosan robot in a custom format
- How to find and set the IP address for connecting a PC to a UR robot — creating a TCP/IP connection between a PC and a Universal Robot
Common mistakes
- Client and server on different subnets. If the client can’t connect, double-check both IP addresses are in the same range and the port is not blocked by a firewall.
- Server IP address is wrong or changes. If the server’s PC gets a new IP (e.g. after a reboot or DHCP renewal), every client needs the updated address.
- Forgetting
data.decode()when printing —recv()returns raw bytes, not a string. - A client hanging forever on
recv()when the server closes unexpectedly — the example above handles this by breaking out of the loop whenrecv()returns empty data (if not data:), but you may want to add a timeout for production use.
Related
Rewritten and consolidated (Sept 2026) from the original student how-to’s: How to create TCP/IP server that can handle multi-client with python (the client could be laptop and robot).