Simple sending .txt file from one computer to anot

2019-03-06 04:21发布

问题:

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 
   +------------+

My problem: there isn't compile errors or syntax errors in both projects, the only problem is that the server doesn't receives the .txt file.

Client:

First I designed a form for the client such as:

And placed an OpenFileDialog from the ToolBox-> Dialogs-> OpenFileDialog control.

Full code:

namespace SFileTransfer
{
    public partial class Form1 : Form
    {
        string n;
        byte[] b1;
        OpenFileDialog op;

        private void button1_Click(object sender, EventArgs e) //browse btn
        {
            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;
                TcpClient client = new TcpClient("127.0.0.1", 8100);//"127.0.0.1", 5055
                StreamWriter sw = new StreamWriter(client.GetStream());
                sw.WriteLine(n);
                sw.Flush();
               // label2.Text = "File Transferred....";
            }
        }
        private void button2_Click(object sender, EventArgs e) //send btn
        {
            TcpClient client = new TcpClient("127.0.0.1", 8100);//5050
            Stream s = client.GetStream();
            b1 = File.ReadAllBytes(op.FileName);
            s.Write(b1, 0, b1.Length);
            client.Close();
           // label2.Text = "File Transferred....";
        }
    }
}

Server:

Created and designed a Form for Server like:

Then Placed a folderBrowserDialog from the ToolBox->Dialogs-> folderBrowserDialog.

Full code:

namespace SFileTransferServer
{
    public partial class Form1 : Form
    {
        string rd;
        byte[] b1;
        string v;
        int m=1;
        TcpListener list;
        TcpClient client;
        Int32 port = 8100;//5050
        Int32 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();

                client = list.AcceptTcpClient();
                MessageBox.Show("ggggggg" + m.ToString());
                Stream s = client.GetStream();
                b1 = new byte[m];

                s.Read(b1, 0, b1.Length);
                MessageBox.Show(textBox1.Text);
                File.WriteAllBytes(textBox1.Text+ "\\" + rd.Substring(0, rd.LastIndexOf('.')), b1);
                list.Stop();
                client.Close();
                label1.Text = "File Received......";
            }
        }
        private void Form2_Load(object sender, EventArgs e)
        {
            TcpListener list = new TcpListener(localAddr, 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();
        }
    }
}

Based on this page

回答1:

I'm assuming you are a new coder because I'm seeing a lot of inefficient code.

On the Client App: Don't redeclare the TcpClient, instead declare it in the global scope and just reuse it.

Then On the server side: Always use the correct datatype IF AT ALL possible

Int16 port = 8100;
//same as
int port = 8100;

Then on to the question: First you are only reading a single byte from the received data

int m=1;
byte[] b1 = new byte[m];
s.Read(b1, 0, b1.Length);
//Then if you know the length of the byte, why do the computation of b1.Length, just use
s.Read(b1, 0, 1);

I see now you are also opeing the connection on the Load event. But that variable is not in the global scope so you are essentially creating a variable in the Load event then after the Load event finishes, sending it to the garbage collection and then declaring a variable with the same name in the button click event.

So try declaring the TcpListener object in the global scope then assign it in the load event and start listening.

Now the AcceptTcpClient() method is a blocking method so it will block your thead until it receives a connection attempt at which point it will return the client object. So try to use this instead: https://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.accepttcpclient(v=vs.110).aspx

using System.Threading;
TcpClient client;
TcpListener server = new TcpListener("127.0.0.1",8100)
Thread incoming_connection = new Thread(ic);
incoming_connection.Start();

private void ic() {
client = server.AcceptTcpClient();
Stream s = client.GetStream();
//And then all the other code
}

Or you can use the Pending method as suggested by MSDN (on the ref page).

EDIT: using threading like this is 'not safe', so if you don't understand threading go read up on it first, this post doesn't cover how to use multi-threading.



标签: c# tcp-ip