0

I'm having a difficult time figuring out how to send and receive an image (and display it, not save it) via UDP socket or named pipe (fifo) on linux.

With UDP sockets the problem I have is the file size exceeds the max buffer size. Conceptually I could iterate over a bytearray of the image in buffer-size chunks, but I'm not sure how to implement this, or how to reconstruct the image on the other side.

With named pipes, below is my code.

p1.py:

fifo_name = "fifoTest"

def Test():
    img = cv2.imread("Lenna.png")
    data = bytearray(img)

    try:
        os.mkfifo(fifo_name)
        print("made fifo")
    except FileExistsError:
        print("fifo exists!")

    with open(fifo_name, "wb", os.O_NONBLOCK) as f:
        f.write(data)
        f.close()
    print("done!")

Some issues with p1 is that I can't seem to figure out when the writing to the pipe has finished, and often time no matter what happens on the other pipe this gives a BrokenPipeError

p2.py:

import os
import io
from PIL import Image
import cv2

pipe = os.open("fifoTest", os.O_RDONLY, os.O_NONBLOCK)
#   img is 117966bytes as given by shell command wc -c < Lenna.png
imgBytes = os.read(pipe, 117966)
#img = Image.open(io.BytesIO(imgBytes))
print(imgBytes)
print(len(imgBytes))
#cv2.imshow("img", img)

input("there?")

With p2 and the commented lines, I have no problems. After input captures my keypress, I get no errors, but as mentioned about p1 errors with broken pipe. When img = Image.open(io.BytesIO(imgBytes)) is uncommented, I get

    img = Image.open(io.BytesIO(imgBytes))
  File "/usr/local/lib/python3.5/dist-packages/PIL/Image.py", line 2585, in open
    % (filename if filename else fp))
OSError: cannot identify image file <_io.BytesIO object at 0x7f21b84b0a98>

I feel like this shouldnt be a hard problem, this is a really basic operation. I need this to happen at about 10fps (which is why I'm not looking at other options). I have also gotten resource temporarily unavailable error a few times, but I think the os.O_NONBLOCK flag fixed that.

Things that I have already looked at (some were helpful, but I need to display an image once its received):

Sending image over sockets (ONLY) in Python, image can not be open

Send image using socket programming Python

File Send by UDP Sockets

Send image using socket programming Python

PIL: Convert Bytearray to Image

Azat Ibrakov
  • 9,998
  • 9
  • 38
  • 50
darrahts
  • 365
  • 1
  • 10
  • Why are you using non-blocking everything? That means you don't care whether data gets sent or received, when you clearly do care. – Mark Setchell Aug 15 '18 at 22:52
  • Because I don't want either side of the pipe to hang. The data will stay in the pipe until the pipe is checked again, that's what nonblocking means. – darrahts Aug 20 '18 at 21:08
  • I don't think that is correct. A send/recv on a non-blocking socket is at liberty to return without doing anything... https://docs.python.org/2/howto/sockets.html – Mark Setchell Aug 20 '18 at 21:26
  • That isn't correct. You are confusing a socket with a pipe. To extend what I meant above non-blocking pipes don't wait on either end to access their end of the pipe. Otherwise, I would have to send part of the image, close the 'write' side of the pipe, and then be able to read the data that was sent. this is inefficient and thats why pipes have a nonblocking flag – darrahts Aug 20 '18 at 21:36

0 Answers0