Python Forum
send all pictures instead of just two
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
send all pictures instead of just two
#4
The problem with using raw sockets is that you need to define your own communication protocol. Here you need some way to tell the client how to separate the images in the data flow. The solution is to send some structured data. For example instead of sending the raw data b'foo-spam-egg' which has length 12, you could send b'12:foo-spam-egg'. The client would know that it must read until b':', then read 12 bytes of data. At the end on each image, you could send a chunck such as b'end:' and the client is now able to distinguish image data from out of band data.

Here is an untested (which means probably broken) implementation for this. See if it works
# SERVER CODE
import socket
import glob
import os
 
host = "127.0.0.1"
port = 5000
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
s.listen(5)
print("server started...")
 
path1 = (r"C:\Users\Desktop\opencvpics")
 
def readFileImages():
    st = os.path.join(path1, "*.jpg")
    print(st)
    return glob.glob(st)
 
def binary_chunks(filename, chunksize=4096):
    with open(filename, 'rb') as f:
        while True:
            s = f.read(chunksize)
            if not s:
                return
            yield s

def send_item(c, chunk):
    prefix = str(len(chunk)).encode()
    c.sendall(prefix + b':' + chunk)
 
while True:
    c, addr = s.accept()
    #print(f"connection from {addr} has been established !")
    #c.send(bytes("welcome to the server".encode()))
    grand_total = 0
    
    for pics in readFileImages():
        print('Sending', pics)
        sent = 0
        for chunk in binary_chunks(pics):
            send_item(c, chunk)
            sent += len(chunk)
        c.sendall(b'end:')
        print("Sent {} bytes for {}".format(sent, pics))
        grand_total += sent
    print('Done sending')
    print('A total of {} bytes were successfully sent.'.format(grand_total))
and the client part
##### CLIENT CODE

import socket
from PIL import Image
import io
 
host =  "127.0.0.1"
port = 5000
 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))


received = 0
buf = [b'']

def get_item(s, buf=buf):
    acc = buf[0]
    while not b':' in acc:
        acc += s.recv(4096)
    prefix, acc = acc.split(b':', 1)
    n = O in prefix == b'end' else int(prefix)
    while len(acc) < n:
        acc += s.recv(4096)
    buf[0] = acc[n:]
    return (prefix, acc[:n])

while True:
    prefix, chunk = get_item()
    received += len(chunk)
    if prefix == b'end':
        print('End of image')
print('Finished receiving. In total, {} bytes were received'.format(received))
s.close()
For me the conclusion is that you are better off using a more structured alternative to raw sockets. There are many. For local usage you could try an xmlrpc server for example or a http server among other possible choices, such as a SSH server.
Reply


Messages In This Thread
send all pictures instead of just two - by mcgrim - Nov-06-2019, 09:35 PM
RE: send all pictures instead of just two - by Gribouillis - Nov-07-2019, 10:12 AM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020