4

I am trying to implenent SocketServer to receive file from mobile application:

  1. Mobile application sends size of file.
  2. Mobile application sends file.

Size of file is received correctly. In application all data is sent. However, SocketServer can't receive all data and sticks.

import SocketServer
import struct

class MyTCPHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        size = self.readLong()
        print 'Payload size', size

        bytes = self.readExact(size)
        print 'Read bytes'

        self.request.sendall('Hurray!')

    def readLong(self):
        return long(struct.unpack('>q', self.readExact(8))[0])

    def readExact(self, num):
        buf = bytearray()
        remaining = num
        while remaining > 0:
            chunk = self.request.recv(remaining)
            if not chunk:
                raise EOFError('Could not receive all expected data!')
            buf.extend(chunk)
            remaining -= len(chunk)
        return buf

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

SOLVED As @6502 suggested, problem was in mobile app where I used buffered output, but never flushed.

Forge
  • 6,538
  • 6
  • 44
  • 64
Tzoiker
  • 1,354
  • 1
  • 14
  • 23

2 Answers2

1

The code seems correct.

Does your recv call return an empty string? If this happens then an error occurred.

Also are you waiting on the mobile side for an ack? If you don't and just quit the mobile side may be the implementation of there closes the endpoint too early not sending all the data.

Another possibility is if the sender is not handling correctly the fact that send may also return a smaller value than the specified size (this happens when the send buffers are full).

6502
  • 112,025
  • 15
  • 165
  • 265
  • Yes, mobile app waits for response. Empty string is returned when app closes its connection due to passed timeout. – Tzoiker May 30 '15 at 19:45
  • 1
    Then I'd say the problem is on the sending size. Do you handle in a similar way the case of `send` returning a smaller amount? This can happen if the sender buffers are full. – 6502 May 30 '15 at 19:51
  • Thanks for response! Indeed sending side problem, used buffered output. Yet another reminder to me to use `flush()`. – Tzoiker May 30 '15 at 20:29
1

As @6502 suggested, problem was in Android mobile app where I used buffered output (BufferedOutputStream), but never flushed. Adding flush() after write() solved the problem.

Tzoiker
  • 1,354
  • 1
  • 14
  • 23