在两个套接字之间中继,中断插入自己的命令

Relay between two sockets, interrupt to plug in own commands

我有一个程序 A 通过 tcp 套接字与机器 B 通信。现在我有自己的应用程序 C,它也需要偶尔与 B 通信。所以我希望 C 双向中继 AB 之间的所有通信。一旦 C 必须与 B 通话,中继将停止,到 B 的套接字应该刷新/清空所有等待数据,C 应该与 B 通信,接收它需要的东西,然后 之间的中继]AB 应该重新开始。

我对 Python 中的套接字很陌生,所以我只知道一些基本命令,需要一些指向正确方向的信息才能知道要阅读什么以及要注意什么(或一个完整的示例,如果有人碰巧已经做过类似的事情)。

由于中继应该 运行 在后台,而 C 正在做其他事情而不是与 B 交谈,我也想知道我是否应该对此使用线程,或者是否有更好的选择(在下面引用的问题中,使用了异步)?

我也发现了这个问题Need help creating a TCP relay between two sockets,据我了解,中继部分应该与我的问题类似,但我真的无法辨别中继在哪里完成。

好的,我明白了。这是我的解决方案,在 class 中实现以控制机器:

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[0] + ':' + str(relayAddr[1]))

            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