Quantcast
Channel: Active questions tagged python - Stack Overflow
Viewing all articles
Browse latest Browse all 16448

Python Socket Send

$
0
0

I'm attempting to transmit CV frames and additional data via a socket in Python. My approach includes a "header" that specifies the data type, its size, and the timestamp of its creation. This method works seamlessly for smaller images (640x480x3), delivering data with minimal latency and ensuring accurate data capture.

Combine data with header

    def encapsulate(self, data, data_type) -> bytes:        # Data should be frame obtained from cap.read(), no need to do anything        if data_type == 'IMAGE':            buffer = cv.imencode('.jpg', data)[1].tobytes()            self.frame_counter += 1        elif data_type == 'SERVO':            ## Tuple of two floads            buffer = struct.pack('ff', *data)        else:            logging.critical("Encapsulate: Data type not supported")            return None        data_type_encode = data_type.encode('utf-8').ljust(8, b'\0')  # Ensure 8-byte length, left justified        header = struct.pack(self.HEADER_FORMAT, data_type_encode,                              len(buffer),                              self.frame_counter if data_type == 'IMAGE' else -1,                              time.time()) # convert to fixed sized bytes        # Split data into chunks        all_data = header + buffer        total_length = len(all_data)        num_chunks = total_length // self.BUFFER_SIZE + (1 if total_length % self.BUFFER_SIZE else 0)        logging.debug(f"Data Length: {len(buffer)}, num_chunks: {num_chunks}")        for i in range(num_chunks):            chunk = all_data[i*self.BUFFER_SIZE : (i+1)*self.BUFFER_SIZE]            yield total_length, chunk # return a generator

send chunk out

    def send_all(self, soc, chunk, length):        while length:            try:                sent = soc.sendall(chunk)            except ConnectionError as e:                logging.error(f"Send: Connection error {e} ")                logging.error(f"Send: Remote host closing the connection, network issues leading to a dropped connection, or attempts to interact with a socket that has already been closed.")                self.remove_socket(soc)                return False            except BlockingIOError as e:                logging.error(f"Send: BlockingIOError {e}")                time.sleep(0.01)                continue            except OSError as e:                logging.error(f"Send: Other OSError {e}")                self.remove_socket(soc)                return False            if sent == 0:                logging.error(f"Send: Sent 0 bytes")            break        return True

Separate header from data

    def decapsulate(self, header) -> tuple:        assert len(header) == self.HEADER_SIZE, f"Invalid header size: {len(header)}"        data_type, total_byte, frame_index, sent_time = struct.unpack(self.HEADER_FORMAT, header)        data_type = data_type.decode('utf-8').rstrip('\0')        assert data_type in ['IMAGE', 'SERVO', 'TEXT'], f'Invalid data type: {data_type}'        if data_type == 'IMAGE':            logging.info(f"Frame index: {frame_index}, time different: {time.time() - sent_time}")        # Returned data_type is a string, total_byte is an integer        return data_type, total_byte

and receiver function similar in socket HOWTO

  def recv_all(self, sock, count):        buf = bytearray()        while count:            try:                newbuf = sock.recv(count)            except OSError as e:                logging.warning(f"Client close with Error: {e}")                newbuf = None            if not newbuf:                 logging.info("Connection closed")                self.remove_socket(sock)                return None            buf.extend(newbuf)            count -= len(newbuf)        return buf

However, when I increase the image size to 1280x720x3, I encounter an error on the receiver's end, indicating a decoding issue. Further investigation revealed that this is due to a buffer full, specifically a BlockingIOError. Im using non-blocking socket.

As a result of this error, the receiver fails to obtain the correct data, leading to decoding problems. I attempted to resolve this by replacing sendall with send and dividing the data into smaller segments, mirroring the approach on the receiver side. Unfortunately, the socket.send() function tends to return 0 after sending a few chunks.

It appears that the buffer on the sender side is unable to transmit data effectively, as indicated by the receiver not receiving any data.

I would appreciate any advice on resolving this issue.

Thank you in advance!


Viewing all articles
Browse latest Browse all 16448

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>