在两个插座之间进行中继,中断以插入自己的命令

2024-04-19 12:21:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个程序a通过tcp套接字与机器B交谈。现在我有自己的应用程序C,也需要每隔一段时间与B交谈一次。所以我希望C双向中继AB之间的所有通信。一旦C必须与B通话,应停止中继,应刷新/删除所有等待数据的B插座,C应与B通话,接收所需信息,然后应重新启动AB之间的中继。你知道吗

我对Python中的sockets非常陌生,所以我只知道一些基本的命令,需要一些指向正确方向的命令来知道要读什么和要注意什么(或者一个完整的例子,如果有人碰巧已经做过类似的事情)。你知道吗

由于中继应该在后台运行,而C正在做与B交谈以外的其他事情,因此我还想知道是应该使用线程还是有更好的替代方法(在下面提到的问题中,使用异步)?你知道吗

我还发现了这个问题Need help creating a TCP relay between two sockets,据我所知,中继部分应该和我的问题相似,但我真的不知道中继是在哪里完成的。你知道吗


Tags: 数据命令程序机器信息应用程序双向事情
1条回答
网友
1楼 · 发布于 2024-04-19 12:21:56

好吧,我想出来了。下面是我的解决方案,在一个类中实现以控制机器:

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                    

相关问题 更多 >