I am trying to send an image via python sockets. I wrote a simple program for doing that.
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?
CodePudding user response:
It's not a peculiarity of "Python sockets", it's actually how TCP sockets behave. When you call a low level function like send
with TCP, it may or may not send every single byte you requested to be sent, and you have to check its return value in order to determine how much was actually sent. In this specific case, you're calling the send
function for every line in the file (because you're using the file descriptor as an iterable). On client side, you try to read up to 1024 bytes from the socket, but just like send, it is not guaranteed you will read all of the data within a single recv
call. Obviously, since your counter is incremented just one time, that means that recv
receives everything in one stand, in that particular occasion. Learn more about sockets, there are many good tutorials and documentations, even on Wikipedia.