Transfer Multiple Files using TCPSocket

Hi,

I’m very new to Xojo’s TCPSocket and I’ve managed to send single files from one PC to another over network. Right now my challenge is how can I send multiple files over network.

I tried looping, here is my sample.

It loops inside the folder and then add the files to TCPSocket to be sent. Which if we do this with big file sizes the app would crash.
I’d like to mention that I added *transfer and #transfer# as start and end to know that we’re sending a file and know how to stop and then save it as a file over the other computer.

[code]if thisDir.isFolder then
For i As Integer = 1 To libs.Count
Dim dirFiles As New FolderItem(thisDir.Item(i).NativePath)
bs = BinaryStream.Open(dirFiles, False)
f = bs.Read(bs.Length)

      if (f <> "") and TCPSocket.IsConnected then
           TCPSocket.Write("*transfer##" + dirFiles.Name + "##")
           TCPSocket.Write(f)
           TCPSocket.Flush
           TCPSocket.Write("#transfer#")
           TCPSocket.Flush
      end if
 Next

end if[/code]

Any recommendations in sending multiple files over network?

Instead of reading the entire file into a string at once with these lines:

         bs = BinaryStream.Open(dirFiles, False)
          f = bs.Read(bs.Length)

try reading and writing the file in chunks:

...
         bs = BinaryStream.Open(dirFiles, False)
         dim L as uint64 = bs.length
         while L > 0
              dim s as string = bs.read(1024) // try higher or lower values here for performance
              L = L - lenb(s)
             TCPSocket.write(s)
         wend
...

What are “big file sizes”? Maybe your app crashes because of the TCPSocket.Flush; remove the flushes, you don’t need them.

First: Create a “header” for the transfer. A MemoryBlock is good for that. In then first bytes you store the size of the header (the MemoryBlock). Store the file size as an UInt64 value. After the file size you write the length of the filename and the filename itself. This altogether is a minimal header for the file transfer. Because the header contains the file size, you don’t need an end marker.

Write the header: TCPSocket.Write (HeaderMemoryBlock)

Create a property “SendStream” as BinaryStream for the socket. After writing the header initialize the SendStream with the file to transfer, read the first MB in a MemoryBlock and write this: TCPSocket.Write (FirstMBMemoryBlock)

In the SendProgress event of the socket, read the next bytes from SendStream in a variable and write this to the socket.

var buffer as MemoryBlock = SendStream.Read (bytesSent) // "bytesSent" ist the event parameter TCPSocket.Write (buffer)

Before reading the next chunk from SendStream check SendStream for “EndOfFile”. If this is “true” your data was completly sent (to the internal socket buffer).

Thanks Michael and Carsten, I’ll try your suggestions. I’ll get back to you guys once I’ve resume my work, thanks again!

Okay here’s what I did and it now works fine.

I sent info first letting the receiver know how big is the file and then split the data as chunks and I did remove the flushes, it did not affect the performance whatsoever in the sending of data.

Thanks Michael and Carsten, you guys gave me an idea to work about :slight_smile: