1

SOLVED using the following: Python Socket Receive Large Amount of Data

I have server and client. I try to send bytes over sockets from client to server. However, when it actually tries to send the bytes, it failed with error: socket.error errno 90 message too long. Is there any way to get over this error?

Client:

from socket import socket, AF_INET, SOCK_DGRAM
import pyscreenshot as ImageGrab

SERVER = 'xxxx.xxxx.xxxx.xxxx'
PORT = 5000

mySocket = socket(AF_INET, SOCK_DGRAM)

while True:
    im = ImageGrab.grab(bbox=(0,27,320,266))
    im.save('test.png')
    myfile = open('test.png')
    bytes = myfile.read()
    mySocket.sendto(bytes, (SERVER, PORT))
    myfile.close()

Server:

from socket import socket, gethostbyname, AF_INET, SOCK_DGRAM
import cv2
from PIL import Image
import io

PORT_NUMBER = 5000
SIZE = 150000

hostName = gethostbyname( '0.0.0.0' )

mySocket = socket(AF_INET, SOCK_DGRAM)
mySocket.bind((hostName, PORT_NUMBER))

while True:
    (data, addr) = mySocket.recvfrom(SIZE)
    image = Image.open(io.BytesIO(data))
    image.save('test.png')
    imga = cv2.imread('test.png', 0)
sys.exit()

So now I use TCP connection.

New client:

from socket import socket, AF_INET, SOCK_STREAM
import pyscreenshot as ImageGrab

SERVER = 'xxxx.xxxx.xxxx.xxxx'
PORT = 5000

mySocket = socket(AF_INET, SOCK_STREAM)
mySocket.connect((SERVER, PORT))

while True:
    im = ImageGrab.grab(bbox=(0,27,320,266))
    im.save('test.png')
    myfile = open('test.png')
    bytes = myfile.read()
    mySocket.sendall(bytes)
    myfile.close()

New Server:

from socket import socket, gethostbyname, AF_INET, SOCK_STREAM
import cv2
from PIL import Image
import io
import time

PORT_NUMBER = 5000
SIZE = 150000

hostName = gethostbyname( '0.0.0.0' )

mySocket = socket(AF_INET, SOCK_STREAM)
mySocket.bind((hostName, PORT_NUMBER))
mySocket.listen(1)
conn, addr = mySocket.accept()

print("Test server listening on port {0}\n".format(PORT_NUMBER))

while True:
    data = conn.recv(SIZE)
    last_time = time.time()
    image = Image.open(io.BytesIO(data))
    image.save('test.png')
    imga = cv2.imread('test.png', 0)
    print('loop took {} seconds'.format(time.time() - last_time))
sys.exit()

So when I try to run both, I get the following error: (important: when i send over the sockets small amount of bytes it is successfuly sent, but when it's quite big amount of bytes the following error occurs)

C:\Users\Tal\test\Scripts\python.exe 

C:/Users/Tal/PycharmProjects/test/tester.py
Test server listening on port 5000

Traceback (most recent call last):
  File "C:\Users\Tal\test\lib\site-packages\PIL\ImageFile.py", line 221, in load
    s = read(self.decodermaxblock)
  File "C:\Users\Tal\test\lib\site-packages\PIL\PngImagePlugin.py", line 621, in load_read
    cid, pos, length = self.png.read()
  File "C:\Users\Tal\test\lib\site-packages\PIL\PngImagePlugin.py", line 115, in read
    length = i32(s)
  File "C:\Users\Tal\test\lib\site-packages\PIL\_binary.py", line 77, in i32be
    return unpack_from(">I", c, o)[0]
struct.error: unpack_from requires a buffer of at least 4 bytes

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:/Users/Tal/PycharmProjects/test/tester.py", line 23, in <module>
    image.save('test.png')
  File "C:\Users\Tal\test\lib\site-packages\PIL\Image.py", line 1935, in save
    self.load()
  File "C:\Users\Tal\test\lib\site-packages\PIL\ImageFile.py", line 227, in load
    raise IOError("image file is truncated")
OSError: image file is truncated

Process finished with exit code 1
Tal Rofe
  • 457
  • 12
  • 46
  • You probably need to use a "stream socket," `SOCK_STREAM`. This is basically the network equivalent of a bidirectional pipe. – Mike Robinson Nov 29 '18 at 01:40
  • The maximum payload size of a UDP packet is 65,507 bytes. If you need to send more than 65,507 bytes, you'll need to split the data up across multiple UDP packets (or use TCP instead, as Mike suggests) – Jeremy Friesner Nov 29 '18 at 01:42
  • @MikeRobinson So just put the `SOCK_STREAM` instead of `SOCK_DGRAM`? what about the port? – Tal Rofe Nov 29 '18 at 01:43
  • @JeremyFriesner Same Q above – Tal Rofe Nov 29 '18 at 01:44
  • For TCP you'll need to call `connect()` to connect the TCP stream, and then call `send()` rather than `sendto()`. You'll have to read up online about how to do it, the comments section here isn't the appropriate mechanism for a TCP tutorial. – Jeremy Friesner Nov 29 '18 at 02:10
  • @JeremyFriesner I edited the main question now – Tal Rofe Nov 29 '18 at 02:21

0 Answers0