views:

93

answers:

3

Hi,

I'm trying to write some data to a raw data socket(around 22 MB's). The scenario is such:- 1. Open local file 2. Read a chunk of bytes. 3. Write it to the Socket 4. Repeat 2 & 3 until the end of the file.

Now the problem is that my code(Below) is not transferring the complete file. It transfers maybe 3 out the the 22 MB with my test file. The trace however is complete and shows complete data being transmitted. I suspect that maybe it starts writing the next chunk before finishing the current one(though I'm not sure).

while(fs.bytesAvailable > 0){
    var readAmount = (fs.bytesAvailable < socketBufferSize) ? fs.bytesAvailable : socketBufferSize;
    seq++;
    air.trace(">"+seq+" WritePacket "+readAmount+" "+fs.position+" "+fs.bytesAvailable);
    fs.readBytes(bytes, 0, readAmount);
    air.trace(bytes.length);
    socket2.writeBytes(bytes, 0, bytes.length);
    socket2.flush();
}
fs.close();
socket2.close();

Above is the code that I'm supposed to be using. I would like to know if I'm doing anything right/wrong.

Inserting a forced delay between write iterations ensures that the file gets completely transferred indicated in the snippet below. However this is not an acceptable solution. I would like to know if there is some event I should be subscribing to or if anything needs to be done differently. The server on the other end is FileZilla FTP Server.

var sendData = function (){
    if(fs.bytesAvailable > 0){
    var readAmount = (fs.bytesAvailable < socketBufferSize) ? fs.bytesAvailable : socketBufferSize;
    seq++;
    air.trace(">"+seq+" WritePacket "+readAmount+" "+fs.position+" "+fs.bytesAvailable);
    fs.readBytes(bytes, 0, readAmount);
    air.trace(bytes.length);
    socket2.writeBytes(bytes, 0, bytes.length);
    socket2.flush();
    }
    else{
        air.trace("Closing Connection");
        fs.close();
        socket2.close();
    }
}
var interval = setInterval(sendData, 100);

Thanks

A: 

Since AIR has a brutal socket close operation, the server needs to be modified to let the client know when it has received all the data sent(via another TCP control Socket). Of course the client needs to relay how much data it is sending at the start.

Iqbal Talaat Bhatti
A: 

It's been a while that i'm waiting for a socket event triggered when data is fully written... :(

The first idea is to put a delay after each write(). However, in case of really good connection, the transfer is longer because of the delay. And in case of slow connection, the delay is not always sufficient and so some data can still be lost :(

The only one solution that i've found is not really proper but works. I'm using proftpd as FTP server with a MOD that i've written that allows a new FTP command : FILESIZE. This command give the size of a filepath in octets.

Then, in flex, i've 2 sockets opened : one for transmitting the data, one to get the filesize. After each call of write() on the first socket, i get the size of the file using FILESIZE on the second socket.

The other side of the coin is that the transfer take much time because of the FTP calls of FILESIZE (:/) but the transfer is more reliable.

This is the kind of problem that will probably move from Flex to Java. Alomost two years that is problem is posted on Adobe Bug pages, and... nothing... Is there a way to add this feature in the core of flex ? I don't think so, flash is not open source...

Vince
Vince. I would be really awesome if you could share the code of the proftpd FILESIZE command MOD.
Iqbal Talaat Bhatti