2

First of all, what I want to do: Sending Photos with Socket from my Raspberry Pi to my laptop.

Client:

#!/usr/bin/python

import socket
import cv2
import numpy as np
import pickle

#Upload image
img = cv2.imread('/path/to/image', 0)

#Turn image into numpy-array
arr = np.asarray(img)

#Receiver ip
ip = "XXX.XXX.X.XXX"

#Set up socket and stuff 
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

#Loop through each array (5 for test)
for each in range(5):

    #Encode each array
    msg = pickle.dumps(arr[each][0])

    #Send msg to ip with port
    s.sendto(msg, (ip, 50000))

s.close()

What happens here: I upload a picture and then turn it into an Numpy array. Then I take each line of the array (each list) and "encode" it with pickle to send it afterwards via Socket. Everything works fine to this point.

Server:

#!/usr/bin/python

import socket
import numpy as np
import cPickle as pickle

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

s.bind(("", 50000)) 

while True:
    data, addr = s.recvfrom(4096)
    conv = pickle.loads(data)
    print conv
    #print np.fromstring(conv,dtype=int)
s.close()

The server receives the encoded data and decodes it back into an Numpy array (that's what I want to achieve).

At the end, it should turn the array back into an image, but I didn't even get to that part, because of the issues I have at this point.

I've also tried to turn the array into a string first, encode it with pickle and then send it so when it gets decoded, it is an numpy array. But that didn't work well.

ValueError: string size must be a multiple of element size

I would appreciate any kind of help, be it a link or pointing out my mistake. Have been working on this for days and haven't found anything that could help me in this matter.

Thanks in advance.

7
  • 1
    I don't know why you don't send image directly as bytes - fh = open(... "rb"), sendto(fh.read()) Commented Oct 30, 2016 at 17:09
  • Could you explain that a bit more? How does the sendto() function work? I'm actually quite new to socket and all that stuff, that's why ^^ Commented Oct 30, 2016 at 17:23
  • Nevermind, I now understand what you mean, but the message gets too long, so it doesn't work. Is there a way to split the data into packages so I send them like that? socket.error: [Errno 90] Message too long Commented Oct 30, 2016 at 17:29
  • you don't have to convert bytes from file into string (or any other thing) to send it. pickle converts Python object into bytes. sendto() always sends bytes. Commented Oct 30, 2016 at 17:30
  • btw. if client sends data longer then 4096 then server has to use recvfrom(4096) in loop to receive all data. Problem is server doesn't know how many times use recvfrom(4096) so first you should send size - and this way you create own "protocol" like other protocols ie. HTTP, FTP. So it is easier to use HTTP. Commented Oct 30, 2016 at 17:38

2 Answers 2

2

You don't need OpenCV and NumPy for this. Instead, simply send the bytes of the file directly. If you have Python 3.5 you can even use socket.sendfile().

For more detail see: Sending a file over TCP sockets in Python

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, but I have already solved it the way furas told me.
0

I dont know how many decimal places you need but you could encode your numpy array values in UTF16 BE and then decode after socket send with

def retrieve_and_decode_data():
    try:
        data,addr = s.recvfrom(4096)                                                                                                                                                                                
        list_of_converted_utf16chars = (repr(data.decode('utf-16')).split("\\")[1:])

    except (ValueError, IndexError) as e:
        **perform some conversion-error exception...**

The "repr" function gives you a representation of the utf16 char you can look up in the utf-table

you can then convert this representation into a int or float with

integer_value = int(list_of_converted_utf16chars[index], 16)

1 Comment

Thank you, but I have already solved it the way furas told me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.