How to send file more then once

微笑、不失礼 提交于 2019-12-04 07:05:55

问题


There are two C# projects: one project is for the client, the other one is for the server. First step is to run the server , then to choose a target folder, after that to run the client project, to choose some text.txt to send to the server's target folder. Only client can send files to the server

Demo:

1.choosing file target                       2.client sends
   +------------+                                
   | tar folder |          <----------------       text.txt 
   +------------+

This works fine, but I want it to send the text.txt automatically every few minutes so I added while(true) loop and Thread.Sleep(10000) but it alaway gives Exceptions. I mean, It's not gives me to send it more then once.

Here the in client class I'm trying to put a while loop :

 public Form1()
        {
            InitializeComponent();
        }


        private void button1_Click(object sender, EventArgs e)//browse btn
        {
            string n;
            byte[] b1;
            TcpClient client;
            OpenFileDialog op;
            Stream s;
            StreamWriter sw;
            op = new OpenFileDialog();

            if (op.ShowDialog() == DialogResult.OK)
            {
                string t = textBox1.Text;
                t = op.FileName;
                FileInfo fi = new FileInfo(textBox1.Text = op.FileName);
                n = fi.Name + "." + fi.Length;

                client = new TcpClient("127.0.0.1", 8100);//"127.0.0.1", 5055

                sw = new StreamWriter(client.GetStream());
                s = client.GetStream();
                b1 = File.ReadAllBytes(op.FileName);

                //  s = client.GetStream();
                while (true)
                {

                    s.Write(b1, 0, b1.Length);
                    sw.WriteLine(n);
                     sw.Flush();
                    //sw.Close();
                    s.Close();//added by me
 Thread.Sleep(18000);

                                   }
                sw.Flush();
                client.Close();

                // label2.Text = "File Transferred....";
            }
        }

Server class:

public Form1()
        {
            InitializeComponent();
        }

        string rd;
        byte[] b1;
        string v;
        int m=20;//number of byts
        TcpListener list;
        TcpClient client;
        int port = 8100;//5050
        int port1 = 8100;//5055
        IPAddress localAddr = IPAddress.Parse("127.0.0.1");
        private void button1_Click(object sender, EventArgs e)//browse button
        {

            if (folderBrowserDialog1.ShowDialog() == DialogResult.OK)
            {

                    textBox1.Text = folderBrowserDialog1.SelectedPath;
                    list = new TcpListener(localAddr, port1);
                    list.Start();

                    Thread incoming_connection = new Thread(ic);
                    incoming_connection.Start();

            }
        }

        private void ic()
        {

            client = list.AcceptTcpClient();
            Stream s = client.GetStream();
            b1 = new byte[m];
            s.Read(b1,0, b1.Length);
            MessageBox.Show("pathh "+textBox1.Text);
            File.WriteAllBytes(textBox1.Text+"\\flag.txt", b1);// the left side us the name of the written file
            //list.Stop();
            //client.Close();
          //  label1.Text = "File Received......";
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            list = new TcpListener(localAddr, port);
           // TcpListener list = new TcpListener(port);
            list.Start();
            TcpClient client = list.AcceptTcpClient();
            MessageBox.Show("Client trying to connect");
            StreamReader sr = new StreamReader(client.GetStream());
            rd = sr.ReadLine();
            v = rd.Substring(rd.LastIndexOf('.') + 1);
            m = int.Parse(v);
           // list.Stop();
           // client.Close();
        }

Related


回答1:


Try changing to:

while (true)
{
    using (var client = new TcpClient("127.0.0.1", 8100))//"127.0.0.1", 5055
    using (var sw = new StreamWriter(client.GetStream()))
    using (var s = client.GetStream())
    {
        b1 = File.ReadAllBytes(op.FileName);
        //  s = client.GetStream();
        s.Write(b1, 0, b1.Length);
        sw.WriteLine(n);
        sw.Flush();
    }
    Thread.Sleep(18000);
}

using statement helps on disposing objects.

Alternativelly, if you want to keep the connection open, try:

using (var client = new TcpClient("127.0.0.1", 8100))//"127.0.0.1", 5055
while (true)
{
    using (var sw = new StreamWriter(client.GetStream()))
    using (var s = client.GetStream())
    {
        b1 = File.ReadAllBytes(op.FileName);
        //  s = client.GetStream();
        s.Write(b1, 0, b1.Length);
        sw.WriteLine(n);
        sw.Flush();
    }
    Thread.Sleep(18000);
}



回答2:


Ok here is your problem:

On the first loop it works fine as expected because everything is initialized correctly but then after it sends the first file you call s.Close();

while (true)
{
s.Write(b1, 0, b1.Length);
sw.WriteLine(n);
sw.Flush();
//sw.Close();
s.Close();//added by me
Thread.Sleep(18000);
}

Now what happens is after the first loop you close the stream and then on the second loop it is already 'Disposed'.

To fix move the s.Close(); out of the loop and into a disconnect button event or the application close event.

Also I would advise against using Thread.Sleep(interval); This is because sleep freezes your thread and the main thread in .NET is used for your interface so freezing that thread is very bad.

Create a new thread like in previous post:

using System.Threading;

Stream s;
byte[] b1;
TcpClient client;
OpenFileDialog op;
StreamWriter sw;
Thread thread = new Thread(sendFile);
string fn;
string n;
threadExit = false;
Int32 interval = 18000;

public Form1()
{
  InitializeComponent();
}
private void Form1_OnLoad(object sender,EventArgs e) {
  op = new OpenFileDialog();
  client = new TcpClient("127.0.0.1", 8100);//"127.0.0.1", 5055
  sw = new StreamWriter(client.GetStream());
  s = client.GetStream();
  //It would be your responsibility to move this code to the proper place
  //because now it tries to open the connection when your app loads
}
private void sendFile() {
  while (!threadExit)
  {
    b1 = File.ReadAllBytes(fn);
    s.Write(b1, 0, b1.Length);
    sw.WriteLine(n);
    sw.Flush();
    Thread.Sleep(interval);
  }
}

private void button1_Click(object sender, EventArgs e)
{
  if (op.ShowDialog() == DialogResult.OK)
  {
    fn = op.FileName;
    FileInfo fi = new FileInfo(textBox1.Text = op.FileName);
    n = fi.Name + "." + fi.Length;
    thread.Start();
  }
  //It would be a good idea to add an indicator to signal that another thread is trying to send the file at a set interval

}
private void Form1_Close(object sender, EventArgs e) {
  s.Close();
  client.Close();
  threadExit = true;
  Application.Exit();
}

And remember to use try catch blocks for this thread otherwise if an exception occurs it wont be handled very good. Also keep in mind that closing the app while this thread is running WILL keep your app open until you manually kill the process, so on the app close event remember to kill the thread.

And also the close is sending a signal for the thread to exit but it can take up to 18 seconds to exit cleanly, another solution is to use thread.Abort(); but thats a dirty exit and it will most likely throw an exception.

And once again rememeber to read up on threading, this is a fast, and BAD, version of how it's supposed to be in a production environment.



来源:https://stackoverflow.com/questions/47752825/how-to-send-file-more-then-once

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!