Aginu
Aginu

Reputation: 136

Python transmitting a file over sockets

I'm trying to transmit a file over sockets which works just fine if I close the connection immediatly after that Now I would like to keep sending commands to the server after the upload is complete, but the server simply ignores them and thinks that there are more lines coming for the file

Here's my code so far Client:

def client_sender():
  global upload
  client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  try:
      print target
      print port
      client.connect((target, port))

      if upload:
          with open(upload_destination, "rb") as f:
              for line in f:
                  client.send(line)
          f.close()
          client.send("DONE\r\n")
          upload = False

      print client.recv(1024)
      buffer = ""
      buffer = sys.stdin.read()
#... some code for sending commands and receiving a response

Server:

def handle_client(client_socket):
    global upload
    print "Client connected"
    if upload:
        file_buffer = ""
        while True:
            data = client_socket.recv(1024)
            if data.rstrip() == "DONE":
                break
            file_buffer += data
        try:
            file_descriptor = open(upload_destination, 'wb')
            file_descriptor.write(file_buffer)
            file_descriptor.close()

            client_socket.send("Successfully placed the file in %s" %upload_destination)
        except:
            client_socket.send("Failed writing to the file")

        upload = False
#... same as client, just some more code for commands

Upvotes: 1

Views: 65

Answers (1)

Valentin Lorentz
Valentin Lorentz

Reputation: 9753

Try printing the value of data after data = client_socket.recv(1024) You will probably see something like: "endofthefile\nDONE\r\n".

So when you run rstrip on that, you would get: "endofthefile\nDONE", which is not equal to "DONE".

You should rewrite your while loop like this:

    while True:
        data = client_socket.recv(1024)
        for line in data.split('\n'):
            if data.rstrip() == "DONE":
                break
            file_buffer += line + '\n'

You may also want to use this on the client side for announcing the end: client.sendall("DONE\r\n"). sendall flushes the client's buffer immediately, instead of waiting for some more data to be sent in the same packet.


Off-topic, but I suggest you change your protocol. It won't work if the file contains the line DONE; and it is unefficient to split lines on the server like that. A better way would be for the client to announce the size of the file, then proceeds to sending it, so the server knows exactly when to stop reading.

Upvotes: 3

Related Questions