From: Andy Baker on
I am trying to transfer a file between a PC and a CE device using sockets.
The file transfer itself is working fine but the CE device side of it is
giving me a problem in that it is not detecting when the transfer is
complete. I am using the OpenNETCF FTP classes as the basis for my code,
which is as follows:-

Filestream output = File.Create(LocalFileName);
Socket socket = OpenDataSocket();
.
.
while(true)
{
try
{
bytesrecvd = socket..Receive(m_buffer, m_buffer.length, 0);
}
catch (SocketException e)
{
}
if (bytesrecvd > 0)
output.Write(m_Buffer, 0, bytesrecvd);
else
break;
}

The file is transferred correctly, but when the transfer is finished, it
hangs at the socket.Receive line waiting for more input. What I want to do
is to set a timeout so that if no more data is received at the socket then
it assumes that the transfer is complete, but it appears that
socket.ReceiveTimeout is not available in the compact framework (I am using
VS2005, CF2).

The same code running on the PC for file transfers in the other direction
works correctly. I have tried setting socket.Blocking = false, but that just
gave me an error straight away without transferring anything. At the PC end,
I have tried using socket.SendFile to send the file in one go, and using
socket.Send to send a byte array 512 bytes at a time in the same way as the
socket.Receive is working on the CE device but I still get the same problem.
If I run the application on the CE device and connect to the FileZilla FTP
server instead of my own PC application is works fine, which suggests that
there is something that I am not doing to tell the device that the transfer
is complete. The code running on the PC is similar (except in VB rather than
C#), and is as follows:-

Dim BUFFER_SIZE As Integer = 512
Dim m_buffer As Byte()
Dim fs As FileStream = New FileStream(FTPPath & ftpCmdtok(1),
FileMode.Open, FileAccess.Read)
Dim intBytesRead As Integer = 0
Do
m_buffer = New Byte(BUFFER_SIZE - 1) {}
intBytesRead += (fs.Read(m_buffer, 0, BUFFER_SIZE))
DataSocket.Send(m_buffer, BUFFER_SIZE, SocketFlags.None)
Erase m_buffer
Loop While intBytesRead < fs.Length
showMessage("226 Transfer OK.")

The PC exits the loop correctly and sends the "226 Transfer OK" message,
which is the signal for the CE device to continue - unfortunately it never
receives it. If I drop the connection from the PC end then I get an
exception at the CE end and can continue with the application, but this is
not the best way to go about it. Any suggestions would be appreciated.
Thanks in advance.

Andy Baker