开发者

asynchronous networkstream to filestream (vice versa)

开发者 https://www.devze.com 2023-02-04 17:58 出处:网络
I have a client/server app. They both use asynchronous calls when receiving data. its build with TCP and is meant, primarily for sending files.

I have a client/server app. They both use asynchronous calls when receiving data. its build with TCP and is meant, primarily for sending files.

A command is sent along a socket which is then 'converted' into and action with a simple switch case. If the client send the command "SENDFILE" I want the server to be able to enter a case which calls a function which then handles any further data along that socket and combines it into a file.

This is OnDataReceive callback function and switch case on the server side:

public void OnDataReceived(IAsyncResult asyn)
        {
            SocketData socketData = (SocketData)asyn.AsyncState;
            try
            {

                // Complete the BeginReceive() asynchronous call by EndReceive() method
                // which will return the number of characters written to the stream 
                // by the client
                socketData.m_currentSocket.EndReceive(asyn);

                //Get packet dtata
                Packet returnPacket = Helper.ByteArrayToPacket(socketData.dataBuffer);

                switch (returnPacket.command)
                {
                    case Command.SENDREQUEST: //Get ready for an incoming file      

Here the class that reads from a network stream asynchronously and write to a filestream synchronously: Is that right?

    public static void NetToFile(NetworkStream net, FileStream file)
        {
            var copier = new AsyncStreamCopier(net, file);
            copier.Start();
        }

public class AsyncStreamCopier
    {
        public event EventHandler Completed;

        private readonly Stream input;
        private readonly Stream output;

        private byte[] buffer = new byte[Settings.BufferSize];

        public AsyncStreamCopier(Stream input, Stream output)
        {
            this.input = input;
            this.output = output;
        }

        public void Start()
        {
            GetNextChunk();
        }

        private void GetNextChunk()
        {
            input.BeginRead(buffer, 0, buffer.Length, InputReadComplete, null);
        }

        private void InputReadComplete(IAsyncResult ar)
        {
            // input read asynchronously completed
            int bytesRead = input.EndRead(ar);

            if (bytesRead == 0)
            {
                RaiseCompleted();
                return;
            }

            // write synchronously
            output.Write(buffer, 0, bytesRead);

            // get next
            GetNextChunk();
        }

        private void RaiseCompleted()
        {
            if (Completed != null)
            {
                Completed(this, EventArgs.Empty);
            }
        }
    }

The problem im having is doing the opposite, reading from a filestream to a networkstream, should I read from the filestream asynchronously and write synchronously to the network stream?

also because with the above example, the first time Start() is called and the function ends it goes back to the server switch case and any further (file)data 开发者_高级运维is then hitting the Packet returnPacket = Helper.ByteArrayToPacket(socketData.dataBuffer);

and erroring :(

*EDIT 1 *

  • I cannot use any external libraries or large amounts of code, this has to be build from the ground up.

  • This is not the typical client-server app, its more p2p but not quite, each app has its own server and client running in different threads, this allows multiple apps to all connect to each other creating a...network.

  • A client tells a server it is sending a file to it, it doesn't request a file from the server


Well, I don't think there is any direct answer to your question; however, here are a few observations:

If the client send the command "SENDFILE" I want the server to be able to...

This is an approach; however, you might look at inverting the control a little more. Have a fetch file info which returns size/version info. Then have a read file that takes an offset and length. Now the client can 'poll' it's way through the file rather than trying to absorb the data as fast as the server can send it.

Here the class that reads from a network stream asynchronously and write to a filestream synchronously: Is that right?

Yea, at a glance that looks right.

The problem im having is doing the opposite, reading from a filestream to a networkstream, should I read from the filestream asynchronously and write synchronously to the network stream?

Again, I would use a client polling loop to pull pieces of the file at a time. This can then also be restarted should the socket be disconnected.

also because with the above example, the first time Start() is called and the function ends ...

Yea this is going to a problem with sockets in general. Your going to have to track some state information with each socket so that you know what to do with the bytes received. Am I writing to a file, am I awaiting a command, etc. Frankly, if I were writing this (which I wouldn't with sockets anyway), I would pack everything into length-prefixed google protobuffer containing details about each request. This allows you to offload the state management to the client rather than tracking it on the server.

Could someone point me in the right direction ? there isn't much on the net from what i can see.

I think the general reason you don't find much on this searching the net is because most (90% or so) don't even try this. Doing this with sockets is difficult, tedious, and extremely error prone. I would not even begin to use raw sockets for communications. Pick any existing client/server transport out there and go with it. My recommendation would probably lean towards WCF if you require examples.

Cheers, and good luck!


I think i've solved one part of it by using a wait event so the function doesn't end and it allows the networkstream -> filestream to complete.

The problem im having now is to so a filestream -> networkstream. "should I read from the filestream asynchronously and write synchronously to the network stream?"


Check out this article on asynchronous stream operations http://msdn.microsoft.com/en-us/magazine/cc337900.aspx (have compact code that copies streams asynchronously).

Your sample code does not use Completed notification that you have... Make sure your outer code waits for stream copy to finish.

0

精彩评论

暂无评论...
验证码 换一张
取 消