Python Forum
Python 2.7 vs Python 3.8 (Socket Module)
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python 2.7 vs Python 3.8 (Socket Module)
#1
Hello. I have developed a program in Python 3.8 that uses socket to communicate. It works great with 3.8. It will return data back in hex like it should. See below.

I have found python 3.8 socket module returns in bytes where python 2.7 return a string.

I am stuck using python 2.7 because the software I am using on the project requires it. I have tried to convert it many ways and I have had no luck. Any help will be appreciated.


result from Python 3.8 (Correct)
############################################################################
sending "43 41 4E 6F 65 46 44 58 01 01 01 00 00 80 00 00 06 00 06 00 10 A0"
waiting to receive
received "b'CANoeFDX\x01\x02\x02\x00\x00\x80\x00\x00\x10\x00\x04\x00\x03\x00\x00\x00\xe3\x1e\xc4\xdb\xd9\xc1\x03\x00\t\x00\x05\x00\x10\xa0\x01\x00\x03'"
closing socket
################################################################################
result from Python 2.7 (Not Correct Response)
#############################################################################
sending "43 41 4E 6F 65 46 44 58 01 01 01 00 00 80 00 00 06 00 06 00 10 A0"
waiting to receive
received "CANoeFDX Ç â£ÿI┬ á "
closing socket
##############################################################################

 #Python 3.8
def Program1():#A010 Shifter Position
    def readResponse(): 
        try:
            # Send data
            print ('sending "%s"' % readVector)
            sent = sock.sendto(y, ServerAddress)
            # Receive response
            print ('waiting to receive')
            # data, server = sock.recvfrom(1024)
            data, server = sock.recvfrom(1024)
            print ('received "%s"' % data)

        finally:
            print ('closing socket')
            # vectorResponse = binascii.hexlify(bytearray(data)) # spits data same as 2.7 but not in byte form
            vectorResponse = data
            # vectorResponse = data # Returns the correct bytes string in hex form in 3.8
            sock.close()
        # responsToPLC = vectorResponse[40:41]
        responsToPLC = vectorResponse
        print (responsToPLC)
        return responsToPLC

    ####---------Read from Vector Box----------#### 
    
    readVector = '43 41 4E 6F 65 46 44 58 01 01 01 00 00 80 00 00 06 00 06 00 10 A0' 
    y = bytearray().fromhex(readVector)

    ####----Below is logic for OUTPUT from Vector Box formatted----####
    readResponse()
Reply
#2
perhaps this will help: https://www.pitt.edu/~naraehan/python2/unicode.html
Reply
#3
Try print ('received "%s"' % repr(data)) so that we can see what the program actually received.
Reply
#4
sending "43 41 4E 6F 65 46 44 58 01 01 01 00 00 80 00 00 06 00 06 00 10 A0"
waiting to receive
received "'CANoeFDX\x01\x02\x02\x00\x00\x80\x00\x00\x10\x00\x04\x00\x03\x00\x00\x00\xa3s\xe8l\x9d\xd4\x03\x00\t\x00\x05\x00\x10\xa0\x01\x00\x02'"
closing socket


The program actually received the correct format that I need. I tried to pull the data using responsToPLC = vectorResponse[40:41][ and the result is still encoded incorrectly.
Reply
#5
MattB Wrote:the result is still encoded incorrectly.
I don't think the result is encoded incorrectly. It is the printing operation that encodes the data. Was your previous post with python 2.7 ?

The server doesn't know whether the client process is using python 3.8 or 2.7, so if the client sends the same request, it must receive the same response.
Reply
#6
Yes the previous post was 2.7. It is receiving exactly what I need to gather the information. I need to figure out how to pull the data from the string.
Reply
#7
In python2, the string is already a binary string, so there is no need to pull the data from the string. Its contents is a sequence of bytes similar to a C char sequence.

Python 3's "string" type is python 2's "unicode" type

Python 3's "bytes" type is python 2's "string" type, with a few differences in the API because in python 3 the sequence is viewed as a sequence of small integers while in python 2 it is a sequence of chars. The contents is the same however.
Reply
#8
Hm, first of all you need something to convert the data.
For example the header itself could be made with a function and parsed with a function:

import struct


def parse_header(frame: Union[bytes, bytearray]):
    """
    UDP Datagram Header The UDP datagram header consists of an FDX signature,
    a two-byte FDX version number (major and minor version),
    the number of commands that follow the header, and a sequence number.
    The signature is an eight-byte,  constant unsigned integer with the value 0x584446656F4E4143
    (“CANoeFDX” in hexadecimal, Intel Format). The signature serves as an
    identifier to determine whether or not the datagram is intended for CANoe.
    CANoe will ignore all datagrams that do not have this exact signature.

    A two-digit version number is used to identify the FDX protocol version and
    the compatible CANoe version. The two digits are represented in two bytes of the UDP header,
    the fdxMajorVersion and fdxMinorVersion fields. A change to the FDX protocol may result in
    a change to the minor version number, but not the major version number.

    This type of change indicates  a potential increase of FDX protocol-specific information within the datagram.
    CANoe can still process the newer datagram using the same major version, but the new information is ignored.
    The version is defined by Vector. At the time of this document’s publish, the current version value is “1.0”
    (major version = 1, minor version = 0).

    The sequence number assists the receiver in recognizing the loss of individual datagrams.

    The sender numbers the datagrams sequentially starting with 0x0001 and ending with 0x7FFF.

    The valid values for the sequence number are as follows:
        •0x0000 - starts a new counting sequence
        •0x0001 - 0x7FFF – valid sequence numbers; once 0x7FFF is reached, sequence number resets to 0x0001
        •0x8000 - ends a counting sequence or indicates that no sequence counting exists
    """
    signature = (0x584446656F4E4143).to_bytes(8, "little")
    fields = namedtuple(
        "header",
        "signature fdxMajorVersion fdxMinorVersion numberOfCommands sequenceNumber reserved",
    )
    header = fields(*struct.unpack("8s2B3H", frame[:16]))
    if header.signature == signature:
        return header
    else:
        return None


def make_header(
    fdxMajorVersion: int = 1,
    fdxMinorVersion: int = 1,
    numberOfCommands: int = 1,
    sequenceNumber: int = 0,
    reserved: int = 0,
):
    """
    UDP Datagram Header The UDP datagram header consists of an FDX signature,
    a two-byte FDX version number (major and minor version),
    the number of commands that follow the header, and a sequence number.
    The signature is an eight-byte,  constant unsigned integer with the value 0x584446656F4E4143
    (“CANoeFDX” in hexadecimal, Intel Format). The signature serves as an
    identifier to determine whether or not the datagram is intended for CANoe.
    CANoe will ignore all datagrams that do not have this exact signature.

    A two-digit version number is used to identify the FDX protocol version and
    the compatible CANoe version. The two digits are represented in two bytes of the UDP header,
    the fdxMajorVersion and fdxMinorVersion fields. A change to the FDX protocol may result in
    a change to the minor version number, but not the major version number.

    This type of change indicates  a potential increase of FDX protocol-specific information within the datagram.
    CANoe can still process the newer datagram using the same major version, but the new information is ignored.
    The version is defined by Vector. At the time of this document’s publish, the current version value is “1.0”
    (major version = 1, minor version = 0).

    The sequence number assists the receiver in recognizing the loss of individual datagrams.

    The sender numbers the datagrams sequentially starting with 0x0001 and ending with 0x7FFF.

    The valid values for the sequence number are as follows:
        •0x0000 - starts a new counting sequence
        •0x0001 - 0x7FFF – valid sequence numbers; once 0x7FFF is reached, sequence number resets to 0x0001
        •0x8000 - ends a counting sequence or indicates that no sequence counting exists
    """
    signature = (0x584446656F4E4143).to_bytes(8, "little")
    return struct.pack(
        "8s2B3H",
        signature,
        fdxMajorVersion,
        fdxMinorVersion,
        numberOfCommands,
        sequenceNumber,
        reserved,
    )
Output:
>>> parse_header(make_header(1,1,1,32768,0)) header(signature=b'CANoeFDX', fdxMajorVersion=1, fdxMinorVersion=1, numberOfCommands=1, sequenceNumber=32768, reserved=0)
What you're currently doing is to interpret hexadecimal data by yourself.
Python 2 allows the mix of str, bytes with leads into chaos.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#9
Thank you all for the help. I was able to get it working and is running well!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  python socket connect only sometimes espDino 0 1,500 Jul-15-2020, 12:13 PM
Last Post: espDino
  how to get your own ip using python (NO SOCKET:) ) julio2000 3 2,254 Mar-02-2020, 09:35 PM
Last Post: buran
  Python module wifi not showing all wireless networks marozsas 3 3,867 Jan-24-2020, 02:59 PM
Last Post: buran
  For Xilinx EthernetLite LWIP:Need help in Python SOCKET Coding Saras 1 2,947 Oct-01-2018, 05:16 AM
Last Post: Saras
  Python Socket programming with packets sourabhjaiswal92 1 4,090 Sep-18-2018, 06:24 AM
Last Post: martingever
  Send data BMP180 between client and server trought module socket smalhao 0 2,805 Jul-30-2018, 12:56 PM
Last Post: smalhao
  Python socket : Error receive data quanglnh1993 1 12,952 Mar-14-2018, 11:59 AM
Last Post: avorane
  Python module for Router configuration parsing anna 0 3,602 Mar-08-2018, 06:02 PM
Last Post: anna
  Python // C # - SOCKET connection is constantly interrupted raspberryPiBRA 0 2,386 Feb-01-2018, 09:53 AM
Last Post: raspberryPiBRA

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020