Asynchronous Socket Transfer in C#

Hi there, I am trying to make an FTP component and I need asynchronous file transfer. For the moment everything works fine, but I want to add a transfer progress bar. To do that I need to track the numer of bytes that have been received by the destination host.

I have to functions: the first one is the one that I call whan I begin a file transfer, and the second one is the callback function for the asynchronous transfer. In the state object I have the file that I will transfer, the socket, and the number of bytes transfered.

I have 2 problems:
1. I want to throw an event when the transfer is completed, but  then Socket.EndSend() method blocks only for the time the bytes are sent, and i actualy need to send the event when the bytes are received. How can I ensure that the bytes have been succesfully received? I mean, after the Socket.EndSend() method returns, even if I close the socket, the data will still arive shortly.

2. I want to throw an event once every 512 bytes are sent. Any idea?

            public void SendFile()
            {
                        m_startTick = Environment.TickCount;

                        // Create the state object.
                        DataStateObject state = new DataStateObject();
                        state.workSocket = m_sock;

                        state.fs = new FileStream(m_filename, FileMode.Open, FileAccess.Read);
                        state.BytesTransfered = 0;

                        m_filesize = (int)state.fs.Length;
                        state.bufferupload = new byte[state.fs.Length];
                        state.fs.Read(state.bufferupload, 0, (int)state.fs.Length);
                        state.fs.Close();

                        // Begin sending the data.
                        m_sock.BeginSend(state.bufferupload, 0, (int)state.bufferupload.Length, 0,
                              new AsyncCallback(SendFileCallback), state);
            }

            private void SendFileCallback(IAsyncResult ar)
            {
                        // Retrieve the socket from the state object.
                        DataStateObject state = (DataStateObject)ar.AsyncState;
                        Socket sock = state.workSocket;

                        // Complete sending the data to the remote device.
                        int bytesSent = sock.EndSend(ar);
                        state.BytesTransfered += bytesSent;

                        m_ftpmonitor.OnPercentTransfered(state.BytesTransfered, m_filesize);

                        sock.Close();
                        m_endTick = Environment.TickCount;
                        m_ftpmonitor.TransferCompleted(
                              state.BytesTransfered, m_endTick - m_startTick);

            }
fulgeru99Asked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
AvonWyssConnect With a Mentor Commented:
1. When you are done sending, you need to send the transfer complete status codce to the client. When this call returns, you can assume that the data was received by the client. If this is not safe enough for you, you can also set a flag and trigger the transfer complete on the next commant issued by the client (since the client will not issue commands other than ABOR while transferring).

2. Make your send buffer 512 bytes large and re-issue a BeginSend until you're done; this will already have the desired result.
0
 
JoeisanerdCommented:
Send 512 bytes at a time in a loop and call your event each time in that loop
0
 
AvonWyssCommented:
Hello fulgeru99,

Thank you for grading the question. But may I ask you to tell me why you gave me a C grade? A C grade, by the EE guidelines, means basically that the answer was not helpful at all (please review the grading guidelines for more information). Since you didn't respond to my post, I have no idea why you gave me such a low grade.
0
 
fulgeru99Author Commented:
well, from all the answers, yours was the best, but it wasn't so usefull as i've expected. meanwhile i have solved the problem, so i wasn't interesed any more in this topic, so it was useless for me to keep it opened. this is why i have graded it even if it wasn't so usefull.

nayway, now i am realy having a big problem with my ftp component. everything is fine since i try to connect to an ftp server that requires a time out somewhere between the beggining of the connection and the requirement of the password. unfortunatly that ftp server is not public so you can't try it out (fenrir.infoiasi.ro). it only accepts ssh connections from outside the infoiasi.ro domain.

i have tryed about 5 c# ftp programs and they all get the same problem.

you are right about the grade. i didn't realised that the c grade is the worst of them. sorry about that :(
maybe you can do something with this sample:
http://www.mping.ro/work/ftp.zip

best regards,
vlad
0
All Courses

From novice to tech pro — start learning today.