Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
Hello,

I'm trying to build a Server\Client program which allows me to transfer multiple files simultaneously between my laptop and home computer. I found in an article that an asynchronous connection allows you to do that, so here's what I've done so far:

The Server

C#
namespace Server
{
    class ClientWrapper
    {
        private TcpClient MyClient = null;

        public delegate void Connect(byte[] data);
        public event Connect eConnect;

        public delegate void Error(string msg);
        public event Error eError;

        public ClientWrapper(TcpClient Client)
        {
            MyClient = Client;
            MyClient.GetStream().BeginRead(new byte[] { 0 }, 0, 0, new AsyncCallback(Read), null);
        }

        private void Read(IAsyncResult Arg)
        {
            byte[] MyChunk = new byte[4096];
            Int32 dSize = 0;
            try
            {
                while (true)
                {
                    dSize = MyClient.GetStream().Read(MyChunk, 0, MyChunk.Length);
                    eConnect(MyChunk);
                    if (dSize == 0)
                        break;
                }
                MyClient.GetStream().BeginRead(new byte[] { 0 }, 0, 0, new AsyncCallback(Read), null);
            }
            catch (Exception ex)
            {
                eError(ex.Message);
            }
        }

        public void Write(byte[] Data)
        {
            try
            {
                MyClient.GetStream().Write(Data, 0, Data.Length);
            }
            catch (Exception ex)
            {
                eError(ex.Message);
            }
        }

    }

    public partial class iServer : Form
    {
        public iServer()
        {
            InitializeComponent();
        }

        private void iServer_Load(object sender, EventArgs e)
        {
            Accept();
        }

        private TcpListener MyListner = null;
        private ClientWrapper MyClient = null;
        private bool Connected = false;

        private void Accept()
        {
            MyListner = new TcpListener(IPAddress.Any, 5555);
            MyListner.Start();
            MyListner.BeginAcceptTcpClient(new AsyncCallback(AcceptCallBack), MyListner);
        }

        private void AcceptCallBack(IAsyncResult Arg)
        {
            MyClient = new ClientWrapper(MyListner.EndAcceptTcpClient(Arg));
            MyClient.eConnect += new ClientWrapper.Connect(Read);
            MyClient.eError += new ClientWrapper.Error(Error);
            Connected = true;
            MyListner.BeginAcceptTcpClient(new AsyncCallback(AcceptCallBack), MyListner);
        }

        private void Error(string msg)
        {
            MessageBox.Show(msg, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        private void Read(byte[] MyChunk)
        {
            FileStream fs = new FileStream("MyFile.ext", FileMode.Append, FileAccess.Write);
            try
            {
                fs.Write(MyChunk, 0, MyChunk.Length);
                fs.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Write(byte[] MyBffer)
        {
            try
            {
                MyClient.Write(MyBffer);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void SendFile_Click(object sender, EventArgs e)
        {
            if (!Connected)
                return;
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    byte[] Data = new byte[1024];
                    Int32 dSize = 0;
                    using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read))
                    {
                        try
                        {
                            while (true)
                            {
                                dSize = fs.Read(Data, 0, Data.Length);
                                Write(Data);
                                if (dSize == 0)
                                    break;
                            }
                            Data = null;
                            MessageBox.Show("done");
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                        }
                    }

                }
            }
        }
    }
}   



The Client

C#
namespace Client
{
    public partial class iClient : Form
    {
        public iClient()
        {
            InitializeComponent();
            button1.Click += new EventHandler(Connect);
        }

        private TcpClient MyClient = null;
        
        private void Connect(object sender, EventArgs e)
        {
            try
            {
                MyClient = new TcpClient("127.0.0.1", 5555);
                MessageBox.Show("Connected");
                button1.Enabled = false;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Read(IAsyncResult Arg)
        {
            FileStream fs = new FileStream("MyFile.ext", FileMode.Create, FileAccess.Write);
            byte[] MyChunk = new byte[4096];
            Int32 dSize = 0;
            try
            {
                while (true)
                {
                    dSize = MyClient.GetStream().Read(MyChunk, 0, MyChunk.Length);
                    fs.Write(MyChunk, 0, dSize);
                    if (dSize == 0)
                        break;
                }
                fs.Close();
                MyChunk = null;
                MyClient.GetStream().BeginRead(new byte[] { 0 }, 0, 0, new AsyncCallback(Read), null);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public void Write(byte[] Data)
        {
            try
            {
                MyClient.GetStream().Write(Data, 0, Data.Length);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void SendFile_Click(object sender, EventArgs e)
        {
            using (OpenFileDialog ofd = new OpenFileDialog())
            {
                if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    byte[] Data = new byte[1024];
                    Int32 dSize = 0;
                    using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read))
                    {
                        try
                        {
                            while (true)
                            {
                                dSize = fs.Read(Data, 0, Data.Length);
                                Write(Data);
                                if (dSize == 0)
                                    break;
                            }
                            Data = null;
                            MessageBox.Show("done");
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                        }
                    }
                }
            }
        }
    }
}


OK, when I try to send a file from the server to the client it doesn't send it. I know that there's something wrong with my code, but I can't figure it out and I wonder if someone could help me with this.

thank you in advance.
Posted
Updated 1-Apr-12 13:20pm
v3
Comments
[no name] 31-Mar-12 22:27pm    
Where are your threads being created?
Sergey Alexandrovich Kryukov 31-Mar-12 23:51pm    
The problem is different (and this is a typical mistake). Please see my answer.
--SA

1 solution

Your mistake on the server side is using the same thread for accepting a new connection and working with a network stream. Such schema cannot work, because your server's thread busy with working with a network stream is unable to accept new connection. Effectively, you defeat the purpose of threading. You need at least two network threads on the server side for these two different activity.

You can find further detail in my past answer:
Multple clients from same port Number[^].

—SA
 
Share this answer
 

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900