Mocktheduck
Mocktheduck

Reputation: 1423

Python struct sending chars

Basically I want to pack and send chars from my client to my server, in Python and I have a string and I'm trying to send its chars one by one like this:

a='abcd'
s.sendall(struct.pack("!c",a[0]))

By this I want to send the letter 'a'. But I get the error 'char format requires a bytes object of length 1'.

I researched and it says that I should put a b before my char like b'a' but since my char is stored in a variable, how do I do that?

Also is there a way to pack a string with struct without doing it char by char?

What I'm trying to do:

        a = 'ab cd ef '
        nrel = len(a)
        c.send(struct.pack("!i", nrel)) //send the length
        for i in range (0,nrel):
            c.send(struct.pack("!c",a[i].encode('ascii'))) //send each char one by one 

And in server:

        nr = c_socket.recv(4096)
        nr = struct.unpack("!i",nr)[0]
        cuv = ''
        for i in range (0,nr):
            el = c_socket.recv(4096)
            ch = struct.unpack("!c",el)[0].decode('ascii') //fails after reading the second letter
            cuv = cuv + ch

Upvotes: 2

Views: 7098

Answers (3)

Izik
Izik

Reputation: 948

I ran into this question since I had same problem, with not enough good answers for new pythonists. So for any one in the future, this answer will be good to send character with known amount:

if you want to send your character, first get their int representation, for each character

for example: 'abc'

a_int = ord('a') # 97
b_int = ord('b') # 98

now pack those letter as signed char, its format is 'b':

data = pack('!bbb', 97, 98, 99)

This is one 'b' for each character. of course u can add other formats. You can find the table with details on each type with it's format here: Format Characters

and send:

clientsocket.sendto(data, (hostname, port))

now in the server:

dataLen = 1000000
data, address = serverSocket.recvfrom(dataLen)
data_in_ints = unpack("!bbb", data)

and for each int you can convert back to char with chr: (example for first element)

char = chr(data_in_ints[0])

Upvotes: 0

Mike Müller
Mike Müller

Reputation: 85492

Encode your string:

a = 'abc'
p = struct.pack("!c", a[0].encode('ascii'))

Unpack and encode as string:

string_a = struct.unpack("!c", p)[0].decode('ascii')

You can also encode the whole string and send the bytes in a loop.

a = 'ab cd ef '.encode('ascii')
nrel = len(a)
send(struct.pack("!i", nrel))
for i in range (nrel):
    send(struct.pack("!b",a[i]))

Upvotes: 3

Avijit Dasgupta
Avijit Dasgupta

Reputation: 2065

Maybe you can try converting string to a bytearray using bytearray("abcd").

Upvotes: 0

Related Questions