尝试使用套接字从 GUI 传递值到另一个应用程序。

huangapple go评论63阅读模式
英文:

Attempting to pass values from GUI to another app with socket

问题

以下是您要的代码的翻译:

如标题所述我试图创建两个独立的应用程序一个是GUI/客户端另一个是控制器/服务器

GUI使用多个滑块从用户那里获取输入并通过套接字将值传输给控制器

控制器接收数据并通过SPI连接将其传输到另一个外围设备

程序传输第一个值然后崩溃我得到的错误信息是这两个
连接被对等方重置的错误和断开的管道错误

GUI代码如下

def Configure(e):
    Command(0, 0, ch0, reg_X, group_0, ch_0, 1)

def dacCommand(bus, dev, dacVar, command, dacGroup, dacChannel, multFac):

    Vref = 3
    offsetCode = 0x1555
    M = 65535
    C = 32768
    Iout = dacVar.get()
    Vout = Iout * multFac

    byte1 = command | dacGroup | dacChannel

    dacCode = math.ceil(Vout * (2**16) / (4 * Vref) + 4 * offsetCode)
    inputCode = math.floor((dacCode - C + (2**15)) * (2**16) / (M + 1))

    d = struct.pack('<H', inputCode)
    data = [0, 0, 0]
    dataCommand = [byte1, d[1], d[0]]

    byte1bin = f'{byte1:08b}'
    byte2bin = f'{d[1]:08b}'
    byte3bin = f'{d[0]:08b}'

    dataString = byte1bin + byte2bin + byte3bin

    client_socket.send(bytes(dataString, "utf-8"))

if __name__ == "__main__":
    window = Tk()
    window.title('DACs board control')
    window.geometry('1920x900')

    tab_control = ttk.Notebook(window)

    tab2 = Frame(tab_control)
    tab_control.add(tab2, text='dev1 control')

    tab_control.pack(expand=1, fill="both")

    ch0 = DoubleVar()
    ttk.Label(tab2, text="ch0 (V)", font=("Calibri", 12)).grid(column=0, row=0, padx=10,
                                                              pady=5)
    ch0Scale = Scale(tab2, from_=0, to=Vmax, resolution=0.05, state="normal", variable=
    ch0, command=Configure, font='Helevetica 11', length=200, width=15).grid(row=1,
                                                                          column=0, pady=5, padx=10, sticky='w')

    mainloop()

控制器代码如下:

if __name__ == "__main__":
    spi = spidev.SpiDev()

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.bind((socket.gethostname(), 1234))
    s.listen(5)

    conn, address = s.accept()
    print(f"Connection from {address} has been established.")
    while True:

        command = conn.recv(24)
        if not command:
            break
        spi.open(0, 0)
        spi.mode = 0b01
        spi.max_speed_hz = 1000000

        part1 = command[:8]
        part2 = command[8: 16]
        part3 = command[16:]
        spi.xfer2([int(part1, 2), int(part2, 2), int(part3, 2)]
        spi.close()

    conn.close()

希望这些翻译对您有所帮助。如果您有任何其他问题,请随时提问。

英文:

As i state in the title i'm trying to create a 2 seperate applications, one being a GUI/client and the other being a controller/server.

The GUI uses several sliders to take an input from the user and transfers the value to the controller through a socket.

The controller receives the data and transfers it to another peripheral device, through a SPI connection.

The program transfers the first value and then proceeds to crash. The errors i get are these two :
error connection reset by peer and error broken pipe.

The gui code is

def Configure(e):
Command(0, 0, ch0, reg_X, group_0, ch_0, 1)
def dacCommand(bus,dev,dacVar,command,dacGroup,dacChannel,multFac):
Vref = 3
offsetCode = 0x1555
M = 65535
C= 32768
Iout=dacVar.get()
Vout=Iout*multFac
byte1 = command|dacGroup|dacChannel
dacCode=math.ceil(Vout*(2**16)/(4*Vref)+4*offsetCode)
inputCode=math.floor((dacCode-C+(2**15))*(2**16)/(M+1))
d = struct.pack(&#39;&lt;H&#39;, inputCode)
data= [0, 0, 0 ]
dataCommand = [byte1, d[1], d[0]]
byte1bin=f&#39;{byte1:08b}&#39;
byte2bin=f&#39;{d[1]:08b}&#39;
byte3bin=f&#39;{d[0]:08b}&#39;
dataString=byte1bin+byte2bin+byte3bin
client_socket.send(bytes(dataString,&quot;utf-8&quot;))
if __name__ == &quot;__main__&quot;:          
window = Tk()
window.title(&#39;DACs board control&#39;)
window.geometry(&#39;1920x900&#39;)
tab_control = ttk.Notebook(        window)
tab2        =         Frame(  tab_control)
tab_control.add(tab2, text= &#39;dev1 control&#39;)
tab_control.pack(expand= 1,  fill= &quot;both&quot;)
ch0 = DoubleVar()
ttk.Label(tab2, text= &quot;ch0 (V)&quot;, font= (&quot;Calibri&quot;, 12)).grid(column= 0, row= 0, padx= 10,     
pady= 5)
ch0Scale = Scale(tab2, from_= 0, to = Vmax, resolution = 0.05, state = &quot;normal&quot;, variable= 
ch0, command= Configure, font=&#39;Helevetica 11&#39;, length = 200, width = 15).grid(row = 1, 
column = 0,  pady = 5, padx = 10, sticky = &#39;w&#39;)
mainloop()

The controller code is :

if __name__ == &quot;__main__&quot;:     
spi=spidev.SpiDev()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)
conn, address = s.accept()
print(f&quot;Connection from {address} has been established.&quot;)
while True:
command = conn.recv(24)
if not command:
break
spi.open(0,0)
spi.mode = 0b01
spi.max_speed_hz = 1000000
part1=command[:8]
part2=command[8: 16]
part3=command[16:]
spi.xfer2([int(part1,2),int(part2,2),int(part3,2)])
spi.close()
conn.close()

答案1

得分: 1

客户端和服务器正在执行单个发送和接收操作,为了解决您的问题,您应该使客户端和服务器通过持续通信来维护连接。

首先,在服务器端,您应该修改您的代码如下:

if __name__ == "__main__":
    # ...

    while True:
        conn, address = s.accept()
        print(f"Connection from {address} has been established.")

        while True:
            command = conn.recv(24)
            if not command:
                break

            # ...

        conn.close()

然后在客户端端:

from tkinter import filedialog

def Configure(e):
    # ...

if __name__ == "__main__":
    # ...
    window.createfilehandler(client_socket, tkinter.READABLE, Configure)

    # ...
    mainloop()
    window.deletefilehandler(client_socket)

它应该可以工作,但由于 recv 可能会出现更多问题,您应该考虑异步编程或多线程。

英文:

The client and server are doing a single send and receive operation, to fix your problem you should make the client and server maintain the connection by a continuous communication.

first on the server side you should modify your code like this:

if __name__ == &quot;__main__&quot;:
# ...
while True:
conn, address = s.accept()
print(f&quot;Connection from {address} has been established.&quot;)
while True:
command = conn.recv(24)
if not command:
break
# ...
conn.close()

then on the client side:

from tkinter import filedialog
def Configure(e):
# ...
if __name__ == &quot;__main__&quot;:
# ...
window.createfilehandler(client_socket, tkinter.READABLE, Configure)
# ...
mainloop()
window.deletefilehandler(client_socket)

it should work but you might have more issues because of recv you should look into asynchronous programming or multithreading.

答案2

得分: 1

Send the bytes. It appears you need to send the input code big-endian, so use &gt; instead of &lt; in the format string and include the command byte. Use sendall to ensure all 3 bytes are sent (very likely even with send() but send() can send less under the right conditions).

data = struct.pack('>BH', byte1, inputCode)
client_socket.sendall(data)

On the client, read the 3 bytes. Note you should check the return value of conn.recv to make sure it actually receives 3 bytes. The value is a maximum to receive.

data = conn.recv(3)
if len(data) != 3:
    # deal with it
spi.xfer2(list(data))  # list on bytes data will return the values,
                      # e.g., b'\x01\x02\x03' returns [1, 2, 3].
                      # May not be needed if the function accepts
                      # byte strings...
英文:

No need to send actual ones and zeros. Send the bytes. It appears you need to send the input code big-endian, so use &gt; instead of &lt; in the format string and include the command byte. Use sendall to ensure all 3 bytes are sent (very likely even with send() but send() can send less under the right conditions.

data = struct.pack(&#39;&gt;BH&#39;, byte1, inputCode)
client_socket.sendall(data)

On the client, read the 3 bytes. Note you should check the return value of conn.recv to make sure it actually receives 3 bytes. The value is a maximum to receive.

data = conn.recv(3)
if len(data) != 3:
# deal with it
spi.xfer2(list(data)) # list on bytes data will return the values,
# e.g., b&#39;\x01\x02\x03&#39; returns [1, 2, 3].
# May not be needed if the function accepts
# byte strings...

huangapple
  • 本文由 发表于 2023年4月4日 16:10:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926969.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定