I have a Programm A talking to machine B over a tcp socket. Now I have my own application C that needs to talk to B every once in a while as well. So I want C to relay all communication between A and B bidirecionally. As soon as C has to talk to B, the relaying shall be stopped, the socket to B should be flushed / emtpied of all waiting data and C should talk to B, receive what it needs, and then the relaying between A and B should start again.
I'm pretty new to sockets in Python so I only know some basic commands and need some pointing in the right direction to know what to read and what to watch out for (or a fully worked example, if someone happens to have done something like that already).
Since the relaying should run in the background while C is doing other stuff than talking to B, I also wonder wheather I should use threads to this or if there is a better alternative (in the question referenced below, asynchronus is used)?
I also found this question Need help creating a TCP relay between two sockets and as far as I understand it, the relaying part should be similiar to my question, but I can't really discern where the relay is done.
Ok, I figured it out. Here is my solution, implemented in a class to control the machine:
import struct import socket import time import threading try: from configparser import ConfigParser except ImportError: from ConfigParser import ConfigParser # ver. < 3.0 class machineClass(): def __init__(self): self.read_config() # gets IP's and Ports for machine and relay socket and stores them in self.machineIP, self.machinePort, self.relayIP and self.relayPort self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.s.connect((self.machineIP, self.machinePort)) self.stopRelayEvent = threading.Event() self.relayStoppedEvent = threading.Event() relaySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) relaySocket.bind((self.relayIP,self.relayPort)) relayThread = threading.Thread(target=self.relay, args=(relaySocket,self.s,self.stopRelayEvent,self.relayStoppedEvent)) relayThread.start() print(" Machine [connected]") def relay(self,relaySocket,machineSocket,stopRelayEvent,relayStoppedEvent): while 1: if not relayStoppedEvent.isSet(): relayStoppedEvent.set() relaySocket.listen(1) # waits for connection from software **B**, in loop because **B** reconnects every now and then. While waiting, connection is not blocked for **C** because relayStoppedEvent is set. relayCon, relayAddr = relaySocket.accept() relayStoppedEvent.clear() print('Connected with Software **B** on ' + relayAddr + ':' + str(relayAddr)) while 1: if not stopRelayEvent.isSet(): if relayStoppedEvent.isSet(): relayStoppedEvent.clear() data = relayCon.recv(84) if len(data) == 0: break # in case connection is lost, break loop and go back to waiting for new connection. machineSocket.send(data) relayCon.send(machineSocket.recv(84)) else: relayStoppedEvent.set() data = relayCon.recv(84) def sendDataToMachine(self,data): # Function for **C** to send data to machine **B** self.stopRelayEvent.set() self.relayStoppedEvent.wait() self.s.send(data) time.sleep(.1) return_data = self.s.recv(84) self.stopRelayEvent.clear() return return_data