Click here to Skip to main content
14,327,288 members
Rate this:
Please Sign up or sign in to vote.
Hi,

I have a tcp sender that send large file over tcp.
I have a receiver that receive the files and save them to disk.
It work great for one file, for multiple files it does not work!
I am googleing a few days, went over almost all articles and did not find a solution.
I would VERY appreciate if someone can help me and make my code run as I need!!!
thanks in advanced!


In the sender , I have a fileSystemWatcher, that watch a folder, and when a file created it takes the file and send it over tcp, by the sender.

Here is the sender code:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Sender
{
    /// <summary>
    /// SocketSender is used to asynchronously listen the client and send file to the client.
    /// </summary>
    public   class SocketSender
    { 
        
        #region Memebers
    
        private  IPEndPoint targetEndPoint = null;
        private bool _isConnected;
        Socket clientSock = null;
        private ManualResetEvent PauseIfDisconnected;

        #endregion


        public SocketSender(IPEndPoint ipEndPoint)
        {
            targetEndPoint= ipEndPoint;
            clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _isConnected = false;
            PauseIfDisconnected = new ManualResetEvent(_isConnected);
        }


        public void Connect()
        {
            try
            {
                while (true)
                {
                    if (!_isConnected)
                    {
                        try
                        {
                            // Connect
                            clientSock = null;
                           clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                            clientSock.Connect(targetEndPoint); //target machine's ip address and the port number

                            PauseIfDisconnected.Set();
                            _isConnected = true;
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("======= ERROR Connect function =====");
                            Console.WriteLine(ex.ToString());
                        }
                    }
                    else
                    {
                        if (!clientSock.Connected)
                        {
                            PauseIfDisconnected.Reset();
                            _isConnected = false;
                            clientSock.Close();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("======= ERROR Connect function =====");
                Console.WriteLine(ex.ToString());
            }
        }
       
 

        /// <summary>
        /// Send file information to client
        /// </summary>
        public void Send(string fileToSend)
        {
            if (targetEndPoint == null)
                return;

            Socket clientSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


            // Turn xml to bytes array
            byte[] fileName = Encoding.UTF8.GetBytes(Path.GetFileName(fileToSend)); //file name

           //This line - read bytes cause after the first time- an exception of :the file is being used by another process. but if I debug it- it works and doesn't fail (why?)
            byte[] fileData = File.ReadAllBytes(fileToSend); //file


            byte[] fileNameLen = BitConverter.GetBytes(fileName.Length); //lenght of file name
          var  clientData = new byte[4 + fileName.Length + fileData.Length];

            fileNameLen.CopyTo(clientData, 0);
            fileName.CopyTo(clientData, 4);
            fileData.CopyTo(clientData, 4 + fileName.Length);


            try
            {
                clientSock.Connect(targetEndPoint);
                clientSock.Send(clientData);
                clientSock.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("======= ERROR Send function =====");
                Console.WriteLine(ex.ToString());

           
            }
           
        }
    }
}


Her is the receive code (a different project):

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Receiver
{

    /// <summary>
    /// AsynchronousClient is used to asynchronously receive the file from server.
    /// </summary>
    public   class AsynchronousClient
    {

        #region Members

          Thread t1;
          int flag = 0;
         IPEndPoint ipEnd = null;
         string folderSavePath;
         public static ManualResetEvent allDone = new ManualResetEvent(false);

        #endregion

         public AsynchronousClient(IPEndPoint ipEndPoint, string fSavePath)
         {
             ipEnd = ipEndPoint;
             folderSavePath = fSavePath;

             t1 = new Thread(new ThreadStart(StartListening));
             t1.Start();
         }


        /// <summary>
        /// Start connect to the server.
        /// </summary>
        public   void StartListening()
        {
            if (ipEnd == null)
                return;

  
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                listener.Bind(ipEnd);
                listener.Listen(100);
                while (true)
                {
                    allDone.Reset();
                    listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
                    allDone.WaitOne();

                }
            }
            catch (Exception ex)
            {

            }

        }

        public   void AcceptCallback(IAsyncResult ar)
        {

            allDone.Set();


            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);


            StateObject state = new StateObject();
            state.WorkSocket = handler;

            // Begin to receive the file from the server.
            handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
            flag = 0;
        }

        string fileSavePath = string.Empty;

        /// <summary>
        /// Receive the file send by the server.
        /// </summary>
        public   void ReadCallback(IAsyncResult ar)
        {
           
            int fileNameLen = 1;
            String content = String.Empty;
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.WorkSocket;
            int bytesRead = handler.EndReceive(ar);
           

            try
            {
                if (bytesRead > 0)
                {

                    if (flag == 0)
                    {

                        //create the folder for saving if needed

                        if (!Directory.Exists(folderSavePath))
                        {
                            Directory.CreateDirectory(folderSavePath);
                        }

                        // Get the filename length from the server.
                        fileNameLen = BitConverter.ToInt32(state.Buffer, 0);
                        string fileName = Encoding.UTF8.GetString(state.Buffer, 4, fileNameLen);

                        fileSavePath = folderSavePath + "\\" + fileName;
                        flag++;
                    }
                    if (flag >= 1)
                    {
                        using (BinaryWriter writer = new BinaryWriter(File.Open(fileSavePath, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)))
                        {
                            if (flag == 1)
                            {
                                writer.Write(state.Buffer, 4 + fileNameLen, bytesRead - (4 + fileNameLen));
                                flag++;
                            }
                            else
                                writer.Write(state.Buffer, 0, bytesRead);

                            writer.Flush();
                            writer.Close();
                        }

                            handler.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0,
                            new AsyncCallback(ReadCallback), state);
                        
                    }

                }
                else
                {
                    handler.Close();
                }
            }
            catch(Exception ex)
            {

            }

        }

      
    }

    }


What I have tried:

I tried to develope a tcp sender that send multiple large files over TCP,
and a receiver, that listen and get the files from TCP and save them to disk.
Posted
Updated 15-Aug-18 6:05am
Comments
Mehdi Gholam 8-Jun-16 4:08am
   
Try sending in blocks.
Richard MacCutchan 8-Jun-16 4:15am
   
You have not explained what happens when you try sending more than one file.
Member 10844632 8-Jun-16 5:01am
   
Something in the receiver does not work as needed. It just throw out of range excption, it seems that it proceed the files together and not one AFTER one or all in PERELAL
Richard MacCutchan 8-Jun-16 5:33am
   
Something in the receiver does not work as needed
Then you need to use your debugger to find out what it is; we cannot guess and we cannot see your screen to know what is happening.
Member 10844632 8-Jun-16 6:46am
   
I meant 'something' - that I do not know what to change in order to run it as needed with multiple files.
The receiver throw out of range exception on recive call back when I send a few files one after one
Richard MacCutchan 8-Jun-16 7:03am
   
And why do you think we would know what to change, with such vague information? As I said before, you need to do some debugging to find out where the error occurs and what value(s) is/are out of range, and why.
Rob Philpott 8-Jun-16 13:45pm
   
Wild guess casually looking at the code. I'd say the use of Waithandles is unusual and unnecessary, and in the receiver the signal comes before the EndAccept, causing it to potentially re-enter on the same instance. Try moving the Set below the EndAccept. Even better, get rid of the Wait handle and do the next BeginAccept immediately after the EndAccept.
Member 13714031 15-Aug-18 14:02pm
   
I need the complete code of file sharing from server to multiple connected clients for just one single file.

1 solution

Rate this:
Please Sign up or sign in to vote.

Solution 1

Just take a short look at your code:
the file is being used by another process

It means your file is being read, and you want to read it again at the same time.

Read once, split it in many blocks, and send this block.
   

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100