pythonlabview

Communicating with different objects in LabVIEW Datasocket server with python


I am trying to communicate with a LabVIEW datasocket server, which seems to be very different in structure to the python socket server than I have seen created. I want to be able to read/write certain objects, but not all. It seems that with my client code, it does connect to the server, but I am unable to read or write to it. It either is forced closed by the server if I am trying to read all data, or if I am trying to write to a specific object, python throws the error: struct.error: bad char in struct format or struct.error: required argument is not an integer if I use N or I in struct.unpack(). Any pointers would be helpful.

import socket
import json #converts data to byte streams
import select
import errno
import numpy
import struct 

def byteswap(i):
    return struct.unpack("!I", struct.pack("!I", i))[0]

HEADER_LENGTH = 200

IP = "localhost"
PORT = 3015 #6341 #8089 #3015
Engine_name = "ArrayTest"

# Create a socket
# socket.AF_INET - address family, IPv4, some otehr possible are AF_INET6, AF_BLUETOOTH, AF_UNIX
# socket.SOCK_STREAM - TCP, conection-based, socket.SOCK_DGRAM - UDP, connectionless, datagrams, socket.SOCK_RAW - raw IP packets
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# Connect to a given ip and port
client_socket.connect((IP, PORT))

# Set connection to non-blocking state, so .recv() call won;t block, just return some exception we'll handle
client_socket.setblocking(True)

while True:
    arr = [1,2,3,4,5,6]
    send_data = byteswap(json.dumps({"test_data":arr}))
    print(send_data)
    client_socket.send(send_data.encode())

Solution

  • Because Labview socket server has some unknown protocols, I ended up deciding to create my own server utilizing TCP through Labview and stripping the data using JSON. It is important to note that JSON is not used until Labview 2013 and Python is not introduced until Labview 2018. The server code that is roughly built is as below.

    import socket 
    import threading
    import json
    
    File_length = 4098 #maximum number of characters that can be passed back and forth. needs to be kept the same as labview
    PORT = 3015
    SERVER = socket.gethostbyname(socket.gethostname())
    ADDR = (SERVER, PORT)
    FORMAT = 'utf-8'
    DISCONNECT_MESSAGE = "!DISCONNECT"
    
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(ADDR)
    
    def handle_client(conn, addr):
        print(f"[NEW CONNECTION] {addr} connected.")
    
        Message_previous = ""
    
        connected = True
        while connected:
            Message = conn.recv(File_length).decode(FORMAT)
            Decoded_message = json.loads(Message)
            if Decoded_message != Message_previous:
                print(Decoded_message)
                Message_previous = Decoded_message
    
            String_arr = Decoded_message["Test Value Arr"]
            print(String_arr)
            print(String_arr[0])
            
    
    def start():
        server.listen()
        print(f"[LISTENING] Server is listening on {SERVER}")
        while True:
            conn, addr = server.accept()
            thread = threading.Thread(target=handle_client, args=(conn, addr))
            thread.start()
            return threading.active_count()
            #print(f"[ACTIVE CONNECTIONS] {threading.active_count() - 1}")
    
    
    print("[STARTING] server is starting...")
    start()
    

    I hope others find the rough setup helpful.