Solved

Asynchronous Socket Transfer in C#

Posted on 2004-04-26
5
4,045 Views
Last Modified: 2012-08-13
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
Comment
Question by:fulgeru99
5 Comments
 
LVL 9

Expert Comment

by:Joeisanerd
ID: 10918655
Send 512 bytes at a time in a loop and call your event each time in that loop
0
 
LVL 23

Expert Comment

by:rama_krishna580
ID: 10919804
0
 
LVL 14

Accepted Solution

by:
AvonWyss earned 500 total points
ID: 10922136
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
 
LVL 14

Expert Comment

by:AvonWyss
ID: 10946727
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
 

Author Comment

by:fulgeru99
ID: 10956877
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

Featured Post

Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
This Micro Tutorial hows how you can integrate  Mac OSX to a Windows Active Directory Domain. Apple has made it easy to allow users to bind their macs to a windows domain with relative ease. The following video show how to bind OSX Mavericks to …
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question