18

I have an array kind of ([1,2,3,4,5,6],[1,2,3,4,5,6]) this. I have to send it over a STREAM/TCP socket in python. Then I have to receive the same array at the receiving end.

timgeb
  • 76,762
  • 20
  • 123
  • 145
sg.dev
  • 319
  • 1
  • 2
  • 9
  • Find some way of encoding it into bytes. What the best way is probably depends on your data. Will you always want to send arrays of small numbers? – Ry- Jun 26 '14 at 05:45
  • as a side note...that looks like a tuple of arrays (lists) , not an actual array. Also....pickle might serve you well : https://docs.python.org/3.2/library/pickle.html?highlight=pickle#pickle – omu_negru Jun 26 '14 at 05:47
  • actually i wanna send a 5x5 matrix, and contains float values.please give me the best way to accomplish that. with code if possible. thank you – sg.dev Jun 26 '14 at 05:55
  • Pickle can serve you well, but remember that unpickling foreign pickles is not safe (i.e. if you can't guarantee the origin of the pickle, then you should probably use some other serialization format like json). – thebjorn Jun 26 '14 at 05:55
  • 3
    Sorry, we don't do your work for you... Tell us what you've tried that didn't work... – thebjorn Jun 26 '14 at 05:56
  • You've asked this question before.. http://stackoverflow.com/questions/24407767/how-to-send-a-large-array-over-tcp-socket-in-python-is-it-possible-to-send – thebjorn Jun 26 '14 at 05:57

4 Answers4

30

Sockets are byte streams, so ideal is to write your protocol (read this)

This is a basic example without protocol and you should care about buffer -> recv(). If it is too small, your data will be chopped off. That's why you should implement a protocol, if you send unknown size of data.

Client:

import socket, pickle

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
arr = ([1,2,3,4,5,6],[1,2,3,4,5,6])
data_string = pickle.dumps(arr)
s.send(data_string)

data = s.recv(4096)
data_arr = pickle.loads(data)
s.close()
print 'Received', repr(data_arr)

Server:

import socket

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while 1:
    data = conn.recv(4096)
    if not data: break
    conn.send(data)
conn.close()
danielpopa
  • 810
  • 14
  • 27
7

You can Serialize the object before sending to socket and at receiving end Deserialize it. Check this

Community
  • 1
  • 1
hashbrown
  • 3,438
  • 1
  • 19
  • 37
7

I solved this problem using json (since I heard pickle is unsafe)

client:

import json
...
arr1 = [1,2,3]
arr2 = [4,5,6]
someVar = 7
data = json.dumps({"a": arr1, "b": arr2, "c": someVar})
socket.send(data.encode())

server:

import json
...
data = socket.recv(1024)
data = json.loads(data.decode())
arr = data.get("a")
var = data.get("c")

Here we deserialize the json string, using data.get("a") which you can interpret as data.a

Leo103
  • 691
  • 7
  • 16
1

I solved this issue by going over each item in the array, adding it to a single string, but with a significant character, such as a greek letter or some other uncommon character, then sending that string over the socket, then splitting the recieved string up back into an array on the other side, and removing all of the 'delimiter' items in the new array.

For Example, The Client side

for item in myArray:
        print("item: ", item)
        myArrayString= myArrayString+ str(item) + "Δ"
    print(myArrayString)
    myServer.send((myArrayString).encode())

and then on the Server:

files = myconnection.recv(50000)
        files = files.decode()
        myArray = files.split('Δ')

        for myItem in myArray:
            print(myItem)
        print("End Of Items in Array")

hope this helps! feel free to ask if you need anything clarified! : )