I would like to ask about your opinion about my code. The idea is simple: I designed my own protocol, where client asks server about the image, and the server sends the image, following the below steps (this is the actual protocol I wanted to implement):
CLIENT SERVER
GET\r\n
----------------------------------->
OK\r\n
<-----------------------------------
GET_SIZE\r\n
----------------------------------->
SIZE 1024\r\n
<-----------------------------------
GET_IMG\r\n
----------------------------------->
IMG_DATA an when image sending is over, EOIMG\r\n
<-----------------------------------
DONE\r\n
----------------------------------->
server disconnects the client
I improved the code as suggested by @TobErnack, but would still like to know your opinion of my improvements. Here's the link to the original question and code:
Network protocol using TCP, sending images through sockets
Everything works (it seems so) but I would like to ask about what else I could possibly improve here.
- Does the implementation reflects in 100% what I wanted to achieve in my protocol flow?
- Are the steps implemented as I wanted them to be in my protocol?
client.py
#!/usr/bin/env python
import socket
import sys
HOST = '127.0.0.1'
PORT = 6666
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = (HOST, PORT)
sock.connect(server_address)
fname = 'fromserver.png'
def recvall(sock, msgLen):
msg = ""
bytesRcvd = 0
while bytesRcvd < msgLen:
chunk = sock.recv(msgLen - bytesRcvd)
if chunk == "": break
bytesRcvd += len(chunk)
msg += chunk
if "\r\n" in msg: break
return msg
try:
sock.sendall("GET\r\n")
data = recvall(sock, 4096)
if data:
txt = data.strip()
print '--%s--' % txt
if txt == 'OK':
sock.sendall("GET_SIZE\r\n")
data = recvall(sock, 4096)
if data:
txt = data.strip()
print '--%s--' % txt
if txt.startswith('SIZE'):
tmp = txt.split()
size = int(tmp[1])
print '--%s--' % size
sock.sendall("GET_IMG\r\n")
myfile = open(fname, 'wb')
amount_received = 0
while amount_received < size:
data = recvall(sock, 4096)
if not data:
break
amount_received += len(data)
print amount_received
txt = data.strip('\r\n')
if 'EOIMG' in str(txt):
print 'Image received successfully'
myfile.write(data)
myfile.close()
sock.sendall("DONE\r\n")
else:
myfile.write(data)
finally:
sock.close()
server.py
# !/usr/bin/env python
import random
import socket, select
from time import gmtime, strftime
image = 'tux.png'
HOST = '127.0.0.1'
PORT = 6666
connected_clients_sockets = []
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((HOST, PORT))
server_socket.listen(10)
connected_clients_sockets.append(server_socket)
def recvall(sock, msgLen):
msg = ""
bytesRcvd = 0
while bytesRcvd < msgLen:
chunk = sock.recv(msgLen - bytesRcvd)
if chunk == "": break
bytesRcvd += len(chunk)
msg += chunk
if "\r\n" in msg: break
return msg
while True:
read_sockets, write_sockets, error_sockets = select.select(connected_clients_sockets, [], [])
for sock in read_sockets:
if sock == server_socket:
sockfd, client_address = server_socket.accept()
connected_clients_sockets.append(sockfd)
else:
try:
data = recvall(sock, 4096)
if data:
txt = data.strip()
print '--%s--' % txt
if txt == 'GET':
sock.sendall('OK\r\n')
elif txt == 'GET_SIZE':
with open('tux.png', 'rb') as f1:
file_size = len(f1.read())
f1.seek(0)
print '--%s--' % file_size
file_size = '%s' % file_size
sock.sendall('SIZE %s\r\n' % file_size)
elif txt == 'GET_IMG':
with open(image, 'rb') as fp:
image_data = fp.read()
msg = '%sEOIMG\r\n' % image_data
sock.sendall(msg)
elif txt == 'DONE':
sock.close()
connected_clients_sockets.remove(sock)
except:
sock.close()
connected_clients_sockets.remove(sock)
continue
server_socket.close()