Click here to Skip to main content
15,886,067 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to send an image via python sockets. I wrote a simple script for doing it.

server.py
import socket
import cv2
import sys

c = 0
q1 = '127.0.0.1'
q2 = 10001

s = socket.socket()
s.bind((q1, q2))
s.listen(5)

image_path = sys.argv[1]
with open(image_path, 'rb') as fh:
    print(fh)
    print(dir(fh))
    l = list(fh)
    print(len(l))
    c, addr = s.accept()
    if c != 0:
        for i in fh:
            c.send(i)


client.py
import socket
import cv2
import time

s = socket.socket()
q = '127.0.0.1'
p = 10001
condition = True
s.connect((q,p))
counter = 0

with open('recieved_image.jpg', 'wb') as fh:
    while condition:
        counter = counter+1
        img = s.recv(1024)
        
        if img == b'':
            condition = False
        fh.write(img)
        
print(counter)


Now this is the problem. In my case, when I run python server.py test.jpg, the length of list(fh) is 374. And those parts from list(fh) are sent one at a time via socket. But when I recieve them from client.py, the counter variable increments only one time. Isn't it supposed to increment until 374? Can someone clarify on the things that I have understood wrong?

What I have tried:

server.py
import socket
import cv2
import sys

c = 0
q1 = '127.0.0.1'
q2 = 10001

s = socket.socket()
s.bind((q1, q2))
s.listen(5)

image_path = sys.argv[1]
with open(image_path, 'rb') as fh:
    print(fh)
    print(dir(fh))
    l = list(fh)
    print(len(l))
    c, addr = s.accept()
    if c != 0:
        for i in fh:
            c.send(i)


client.py
import socket
import cv2
import time

s = socket.socket()
q = '127.0.0.1'
p = 10001
condition = True
s.connect((q,p))
counter = 0

with open('recieved_image.jpg', 'wb') as fh:
    while condition:
        counter = counter+1
        img = s.recv(1024)
        
        if img == b'':
            condition = False
        fh.write(img)
        
print(counter)
Posted
Updated 4-Aug-22 22:23pm
v2

1 solution

Using a for loop:
Python
for i in fh:
    c.send(i)

Is the wrong way to do it. A binary file has no concept of 'lines' or records, so Python will read it one byte at a time. You should use the read(size) function to read blocks of data until all the file has been processed.
 
Share this answer
 
Comments
crypL edEntity 5-Aug-22 5:59am    
But list(fh) was a 374 long list. therefore fh is iterable and the code works.
Richard MacCutchan 5-Aug-22 7:25am    
Yes, but only 1 byte at a time, if you use fh.read(x), where x is some block size it will be more efficient.

The reason it works is that TCP/IP is quite clever and packages up the bytes until it gets a full block of data to send, which it then sends to the receiver.

See https://www.baeldung.com/cs/tcp-max-packet-size#:~:text=The%20maximum%20size%20of%20a,size%20should%20never%20exceed%20MTU.[^], for details of how TCP/IP works.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900