Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4059
  • Last Modified:

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);

            }
0
fulgeru99
Asked:
fulgeru99
1 Solution
 
JoeisanerdCommented:
Send 512 bytes at a time in a loop and call your event each time in that loop
0
 
AvonWyssCommented:
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
 
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now