Pyhton Socket, inviare un valore float

di il
9 risposte

Pyhton Socket, inviare un valore float

Salve a tutti,
vorrei inviare, via socket, una variabile di tipo float.
Nell'esempio che segue, si invia una stringa:

#!/usr/bin/env python3

import socket

HOST = '127.0.0.1'
PORT = 80
DATA="Hello World!"

clientSocket= socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientSocket.connect((HOST, PORT))
clientSocket.send(DATA.encode())
clientSocket.close()
La funzione encode() converte la stringa in "bytes-object" per inviarla al server, ma tale funzione non si può usare per una variabile float, infatti se sostituisco alla stringa una variabile float, mi dice che l'oggetto float non ha l'attributo encode.

DATA2=float(1.2)
.
.
.
clientSocket.send(DATA2.encode())
Infatti restituisce questo errore:

    clientSocket.send(DATA2.encode())
AttributeError: 'float' object has no attribute 'encode'
E' possibile inviare una variabile di tipo Float?

9 Risposte

  • Re: Pyhton Socket, inviare un valore float

    Converti il float in una stringa... D'altronde non sai come è strutturata la variabile di tipo float dall'altra parte (e neppure se ci sia il tipo float...)
  • Re: Pyhton Socket, inviare un valore float

    Andrea Quaglia ha scritto:


    Converti il float in una stringa...
    Non lo posso fare, perché, dall'altra parte, un server in Java, si aspetta una variabile di tipo Float.
  • Re: Pyhton Socket, inviare un valore float

    Chi ha scritto il server java? È sullo stesso server fisico?
  • Re: Pyhton Socket, inviare un valore float

    Non puoi convertire in bytearray e inviare quelli?
    
    import struct
    x = 3333.5 # IEEE-754 0x45505800
    ba = bytearray(struct.pack(">f", x))  
    print(hex(ba[0]))
    print(hex(ba[1]))
    print(hex(ba[2]))
    print(hex(ba[3]))
    ba = bytearray(struct.pack("<f", x))  
    print(hex(ba[0]))
    print(hex(ba[1]))
    print(hex(ba[2]))
    print(hex(ba[3]))
    
  • Re: Pyhton Socket, inviare un valore float

    Il server è scritto in Java ed è remoto.
    Il codice che esegue per ricevere una stringa, una variabile intera, ed variabile una in virgola mobile è il seguente:
    
    DataInputStream rx = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
    System.out.println(rx.readLine());
    System.out.println(rx.readInt());
    System.out.println(rx.readFloat());
    
    Ho risolto il problema utilizzando "struct.pack", solamente non mi è chiaro una cosa:
    
    data2 = struct.pack('!i', 3)  # integer -> bytes
    
    mi invia una variabile di tipo intero;
    
    data3 = struct.pack('!f', 3.14)  # float -> bytes
    
    mi invia una variabile di tipo float;

    Per inviare una stringa, invece, ho trovato diversi modi, riportati qui sotto:
    
    data1="Hello World!\n"
    
    #1:
    packed = data1.encode()
    
    #2:
    packed = bytes('Hello World!\n','utf-8')
    
    #3:
    packed = struct.pack('13s', data1.encode('UTF-8'))
    
    Funzionano tutti e tre, ma qual'è la differenza?

    Inoltre ho questo errore qui: Se volessi utilizzare la soluzione 3, utilizzando però "len" per contare la lunghezza della stringa, invece di mettere il valore a mano, in questo modo:
    
    packed = struct.pack('len(data1)s', data1)
    
    mi restituisce il seguente errore:
    
        packed = struct.pack('len(data1)s', data1.encode('UTF-8'))
    struct.error: bad char in struct format
    
    Come mai? non posso utilizzare len all'interno di quella istruzione?
  • Re: Pyhton Socket, inviare un valore float

    java999 ha scritto:


    
    packed = struct.pack('len(data1)s', data1)
    
    mi restituisce il seguente errore:
    
        packed = struct.pack('len(data1)s', data1.encode('UTF-8'))
    struct.error: bad char in struct format
    
    Come mai? non posso utilizzare len all'interno di quella istruzione?
    In pratica stai inviando la stringa 'len(data1)s' al metodo pack. Ovviamente ti ritorna un errore. Prova così:
    packed = struct.pack(str(len(data1))+'s', data1.encode('UTF-8'))
  • Re: Pyhton Socket, inviare un valore float

    Andrea Quaglia ha scritto:


    In pratica stai inviando la stringa 'len(data1)s' al metodo pack. Ovviamente ti ritorna un errore. Prova così:
    packed = struct.pack(str(len(data1))+'s', data1.encode('UTF-8'))
    Funziona, grazie.
  • Re: Pyhton Socket, inviare un valore float

    java999 ha scritto:


    Salve a tutti,
    vorrei inviare, via socket, una variabile di tipo float...
    Ora dovrei fare l'inverso, dal server Java, ricevere una variabile di tipo float.
    Ho provato con "struct.unpack", ma mi da errore.
    Il codice è il seguente:
    
    data = socket.recv(1024)
    data = struct.unpack('!f', data)
    
    e mi restituisce il seguente errrore:
    
        data = struct.unpack('!f', data)
    struct.error: unpack requires a buffer of 4 bytes
    
    Per ora ho risolto, momentaneamente, concatenando due letture del socket, in questo modo:
    
    rx_1 = socket.recv(1024)
    rx_2 = socket.recv(1024)
    rx = rx_1 +rx_2
    data = struct.unpack('!f', rx)
    print(data)
    
    Un valore float, inviato, 2.7, mi resituisce (2.700000047683716,), compreso le parentesi e la virgola finale, ma penso che sia l'output di "struct.unpack". Come posso ottenere il valore finale, arrotondato ad un decimale, come il valore inviato, 2.7, senza parentesi e virgola?

    "recv", inoltre, quanto legge?
    dal sito ufficiale: https://docs.python.org/3/library/socket.htm
    socket.recv(bufsize[, flags])

    Receive data from the socket. The return value is a bytes object representing the data received. The maximum amount of data to be received at once is specified by bufsize. See the Unix manual page recv(2) for the meaning of the optional argument flags; it defaults to zero.

    Note

    For best match with hardware and network realities, the value of bufsize should be a relatively small power of 2, for example, 4096.
    Ho provato a cambiare il valore con multipli di 1024 (1024,2048,4096,8192), ma non cambia nulla, devo fare sempre due letture.
  • Re: Pyhton Socket, inviare un valore float

    Il valore che vedi è corretto: è il float più vicino a 2.7, il quale non ha una rappresentazione esatta come float a 32 bit

    Per il socket può capitare che i messaggi inviati vengano spezzettati: succede nel TCP e non dipende da te. Devi gestire i pezzi che ti arrivano (tu l'hai fatto indirettamente, ma dovresti gestire spezzoni di qualsiasi lunghezza)
Devi accedere o registrarti per scrivere nel forum
9 risposte