[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

ASYNC Socket, How to use the BeginSendFile?

Posted on 2011-04-28
11
Medium Priority
?
2,031 Views
Last Modified: 2012-05-11
I've written a class using Sockets.  I've noticed that there's a BeginSendFile method in the sockets.  The only code sample i've found was on MSDN, and it doesn't show much thing... (it show the code on the sender side only.   Nothing about the receiver.  I don't know where the file is stored, how it's received, etc).

Is there anyone who could help me with some code:
to send a file
to receive file
to show the progression of the file transfer

Thanks for your help
0
Comment
  • 7
  • 4
11 Comments
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 35487799
Hi, well I think that the MSND documentation is very complete in this case (BeginSendFile method):
http://msdn.microsoft.com/en-us/library/ac1zy13z.aspx

But I dont think that you can know the progress by using the BeginSendFile (maybe making a new class that inherit from System.Net.Sockets.Socket?) method, instead you must use the BeginSend method to be able to know the send progress.
http://msdn.microsoft.com/en-us/library/7h44aee9.aspx
0
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 35487803
MSDN sorry...
0
 
LVL 10

Author Comment

by:Christian de Bellefeuille
ID: 35491096
You probably just have checked the MSDN without trying this sample right?

Because this example throw an error (i'll translate because my compiler is in french):
"Impossible to cast object of type 'System.Net.Sockets.TransmitFileOverlappedAsyncResult' in type 'System.Net.Sockets.Socket'"

And as i said... this method is really not well documented because it doesn't explain how it's received, just how it's sent.
0
Veeam Disaster Recovery in Microsoft Azure

Veeam PN for Microsoft Azure is a FREE solution designed to simplify and automate the setup of a DR site in Microsoft Azure using lightweight software-defined networking. It reduces the complexity of VPN deployments and is designed for businesses of ALL sizes.

 
LVL 10

Author Comment

by:Christian de Bellefeuille
ID: 35492955
Anyone else really have tried this method?
0
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 35493006
Yes Im done an example for you, wait a moment...
0
 
LVL 17

Accepted Solution

by:
Carlos Villegas earned 2000 total points
ID: 35493051
Ok, you are right, that documentation is a mess... well, starting from that documentation and other sources I did this small example, that of course is not well designed, is just for demo purposes of how to listen for a connection and how to send end receive data by using the method that your want:

This is the code, please paste it into a console application:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace SocketsTest
{
    class Program
    {
        static System.Threading.AutoResetEvent listenerEvent = new System.Threading.AutoResetEvent(false);
        static System.Threading.AutoResetEvent clientEvent = new System.Threading.AutoResetEvent(false);
        static System.Threading.AutoResetEvent socketEvent = new System.Threading.AutoResetEvent(false);

        static byte[] buffer = new byte[1024];
        static System.IO.BinaryWriter bw = new System.IO.BinaryWriter(new System.IO.MemoryStream());

        static void Main(string[] args)
        {
            Console.WriteLine("Starting listener...");
            System.Threading.Thread thServer = new System.Threading.Thread(new System.Threading.ThreadStart(AsynchronousListener));
            thServer.Start();

            Console.WriteLine("Client will start in two seconds...");
            System.Threading.Thread.Sleep(2000);

            System.Threading.Thread thClient = new System.Threading.Thread(new System.Threading.ThreadStart(AsynchronousFileSend));
            thClient.Start();

            thClient.Join();
            thServer.Join();
        }


        public static void AsynchronousListener()
        {
            // Send a file to a remote device.

            // Local Loopback IP (127.0.0.1), por 11000
            IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 11000);

            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            // Prepare to listen.
            listener.Bind(localEP);
            listener.Listen(-1);

        //waitForOther:
            Console.WriteLine("Listener started!");
            IAsyncResult acceptResult = listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
            listenerEvent.WaitOne();

            Console.ReadKey();
            //goto waitForOther;

            // Release the socket.
            //listener.Shutdown(SocketShutdown.Both);
            //listener.Close();
        }

        private static void AcceptCallback(IAsyncResult ar)
        {
            // Retrieve the socket from the state object.
            Socket listener = (Socket)ar.AsyncState;
            Socket socket = listener.EndAccept(ar);

            // Start read received data
            Console.WriteLine("Start receiveing data...");
            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), socket);
            socketEvent.WaitOne();

            listenerEvent.Set();
        }

        private static void ReceiveCallback(IAsyncResult ar)
        {
            // Retrieve the socket from the state object.
            Socket socket = (Socket)ar.AsyncState;

            // Read received data.
            int bytes = socket.EndReceive(ar);
            while (bytes > 0)
            {
                bw.Write(buffer, 0, bytes);
                if (bytes < buffer.Length)
                    break;
                bytes = socket.Receive(buffer, 0, buffer.Length, SocketFlags.None);
            }
            Console.WriteLine("End receiveing data... (" + bw.BaseStream.Position + " bytes)");
            
            // Write received file to disk
            bw.Flush();
            using (System.IO.FileStream fs = System.IO.File.Create("C:\\TextReceived.txt"))
            {
                ((System.IO.MemoryStream)bw.BaseStream).WriteTo(fs);
            }

            socketEvent.Set();
        }

        public static void AsynchronousFileSend()
        {
            Console.WriteLine("Client started!");

            // Send a file to a remote device.

            // Local Loopback IP (127.0.0.1), por 11000
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Loopback, 11000);

            // Create a TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            // Connect to the remote endpoint.
            IAsyncResult connectResult = client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
            Console.WriteLine("Client connected!");

            // Wait for connect.
            clientEvent.WaitOne();

            // There is a text file test.txt in the root directory.
            string fileName = "C:\\test.txt";

            // Send file fileName to the remote device.
            Console.WriteLine("Sending file: " + fileName);
            IAsyncResult sendFileResult = client.BeginSendFile(fileName, new AsyncCallback(FileSendCallback), client);
            clientEvent.WaitOne();

            // Release the socket.
            client.Shutdown(SocketShutdown.Both);
            client.Close();
        }

        private static void ConnectCallback(IAsyncResult ar)
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;
            client.EndConnect(ar);
            clientEvent.Set();
        }

        private static void FileSendCallback(IAsyncResult ar)
        {
            // Retrieve the socket from the state object.
            Socket client = (Socket)ar.AsyncState;

            // Complete sending the data to the remote device.
            client.EndSendFile(ar);
            clientEvent.Set();
        }
    }
}

Open in new window


Or download the file:
Program.cs

I did take info from this link too:
http://www.gamedev.net/topic/199400-c-sockets/
0
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 35493795
By the way, the progression of the file transfer can be done on the server side (receiver) but first you need to implement a header or something that send to the client the total file lenght before start transfer the file data, with that you can calculate the progress, on the client side (sender), I think that you need to use another method instead of SendFile (maybe the Send method(a, b, c)), in that way you can know who much data has been sent.

Have you seen the System.Net.Sockets.TcpClient and System.Net.Sockets.TcpListener classes? this are more simplified to use.
0
 
LVL 10

Author Comment

by:Christian de Bellefeuille
ID: 35512881
Ok, so the BeginSendFile still send data the same way that i would do with BeginSend.

Of course i've seen TCPClient and TCPListener, but as you might also notice, there's no SendFile or anything that look like that in these classes.  We have developped our communication class based on the Socket, and it's working at 100%.  

It's just that there was a "BeginSendFile", i was wondering what could be done with it, and if it was doing a good job.   But as far as you have shown me, all what it does is opening the file for me, read it, then it's basically a BeginSend of bunch of data.   I was expecting more of it...

So thanks for your help.  I might use it to save a couple of lines of code.  But my guess is that i'll create an additionnal socket connection just for the file transfer, because our application is a VNC like app and sending a large file could simply take over all the communication for a while.

0
 
LVL 10

Author Closing Comment

by:Christian de Bellefeuille
ID: 35512895
and thanks for that link...
0
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 35512953
Yes, SendFile is just a plus ;) and I agreed with open a new connection for the file transfer.
0
 
LVL 17

Expert Comment

by:Carlos Villegas
ID: 35512960
Glad to help!
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

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

Many of us here at EE write code. Many of us write exceptional code; just as many of us write exception-prone code. As we all should know, exceptions are a mechanism for handling errors which are typically out of our control. From database errors, t…
High user turnover can cause old/redundant user data to consume valuable space. UserResourceCleanup was developed to address this by automatically deleting user folders when the user account is deleted.
In a question here at Experts Exchange (https://www.experts-exchange.com/questions/29062564/Adobe-acrobat-reader-DC.html), a member asked how to create a signature in Adobe Acrobat Reader DC (the free Reader product, not the paid, full Acrobat produ…
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…
Suggested Courses

831 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