vampierke33
vampierke33

Reputation: 31

Calling sock.recv() after sock.sendall() in Python

I provided a WORKING client and server file. The client sends a picture to the server. When you comment out:

data = sock.recv(1024)
print("received: ",str(data,"UTF-8"))

the picture will not be uploaded to the server anymore... (After receiving the upload message from the server I would like to upload another picture in the future.)

So why is calling sock.recv() after sock.sendall() messing up the communication ? ( and how should I solve it )

Client.py :

import socket
PICLOC = "/home/wr/Documents/Data/cola_big_1.jpg"
HOST = 'localhost'
PORT = 9995

# Create a socket (SOCK_STREAM means a TCP socket)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

try:

   # Connect to server and send data
   sock.connect((HOST, PORT))

   # Send a command to the server
   command = "pictureRequest"
   data = sock.send(bytes(command, "utf-8"))

   pictures = []
   pictures.append(PICLOC)

   data = sock.recv(1024)
   print("received : ",data.decode())

   for picture in pictures:
       # sending a picture to the server
       f = open(picture,'rb').read()
       numBytes = len(f)
       x = str(numBytes)
       print("numBytesToSend: ",x)
       data = sock.sendall(f)
       '''
       data = sock.recv(1024)
       print("received: ",str(data,"UTF-8"))
       '''
finally:
   sock.close()

Server.py

import socketserver

HOST = "localhost"
PORT =  9995

TARGETPICLOC = "/home/wr/Documents/Data/Received/cola_big_1.jpg"

class MyTCPHandler(socketserver.BaseRequestHandler):


  def findProduct(self):
    """
        Method called to find the product
    """

    # Receiving command from the client
    msg = "ok to send" 
    data = self.request.sendall(bytes(msg,"utf-8"))
    print("send msg")

    # TODO 6 pictures in array !
    # Sending a picture from client to server  
    pictures = []
    pictures.append(TARGETPICLOC)


    for picture in pictures:
        total_data=[]

        # open the target picture-file 
        newFile = open(picture,'wb')

        data = self.request.recv(1024)
        newFile.write(data)
        total_data.append(data)
        while len(data)>0 :
            data = self.request.recv(1024)
            newFile.write(data)
            total_data.append(data)

        data = b''.join(total_data)
        print("#bytes : ",len(data))
        newFile.close()

        msg = "picture uploaded"
        data = self.request.sendall(bytes(msg,"utf-8"))
        print("msg send ")


  def handle(self):

    # Receiving command from the client
    data = self.request.recv(1024)
    command = str(data,"utf-8")
    print("command: ",command)

    if command=="pictureRequest" :
        self.findProduct()

    print("Request ended !!")



if __name__ == "__main__":
   HOST, PORT = HOST,PORT
   server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
   server.serve_forever()

Thank you for looking at this problem

Upvotes: 3

Views: 3262

Answers (1)

Armali
Armali

Reputation: 19395

So why is calling sock.recv() after sock.sendall() messing up the communication ?

That's simply because the client by this sock.recv() call waits for data from the server (you intend to receive the picture uploaded message from the server), but the server is stuck in the loop

        while len(data)>0 :
            data = self.request.recv(1024)

since recv() still waits for data from the client and blocks. If the sock.recv() call is omitted, the client gets to sock.close(); only thereafter self.request.recv(1024) returns zero length data, so that the server can sense the end of the transmission and escape the while loop.

( and how should I solve it )

You could send the number of bytes to send (x = str(numBytes)) to the server prior to sending the picture, so that the server then could loop while the length of total_data is less than this number.

Upvotes: 2

Related Questions