发送带有套接字的大文件到服务器 C#

sending big file with socket to server c#

我正在尝试向服务器发送一个大约 250 kb 的文件,但我遇到了损坏,而且似乎完全只传输了一些字节。命令流程是 写入流:Send\r\n 写入流:FileName\r\n 写入流:FileData \r\n 关闭连接 这是代码:

        TcpClient sendClient = new TcpClient(serverName, port);
        SslStream sendStream = new SslStream(sendClient.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
        try
        {

            sendStream.AuthenticateAsClient(serverName, null, SslProtocols.Ssl2, true);




            sendStream.Write(Encoding.UTF8.GetBytes("Login\r\n" + username + "\r\n" + password + "\r\n"));
            sendStream.Flush();
            int bytesResp = -1;
            byte[] buffer = new byte[1026];

            bytesResp = sendStream.Read(buffer, 0, buffer.Length);

            string response = Encoding.UTF8.GetString(buffer, 0, bytesResp);

            if (response.Trim() == "OK")
            {

                byte[] fileNameByte = Encoding.UTF8.GetBytes(fileName + "\r\n");
                byte[] fileData = File.ReadAllBytes(filePath);
                  byte[] newLine = Encoding.ASCII.GetBytes("\r\n");

                byte[] clientData = new byte[4 + Encoding.ASCII.GetBytes("Send\r\n").Length + fileNameByte.Length + fileData.Length+newLine.Length];



                byte[] fileNameLen = BitConverter.GetBytes(fileNameByte.Length);

                byte[] send = Encoding.ASCII.GetBytes("Send\r\n");



                send.CopyTo(clientData, 0);
                fileNameLen.CopyTo(clientData, 4 + send.Length);
                fileNameByte.CopyTo(clientData, send.Length);
                fileData.CopyTo(clientData, 4 + fileNameByte.Length + send.Length);
                newLine.CopyTo(clientData, 4+ fileNameByte.Length + send.Length + fileData.Length);

                MessageBox.Show(clientData.Length.ToString());






                sendStream.Write(clientData, 0, clientData.Length);

                sendStream.Flush();
                sendStream.Write(Encoding.UTF8.GetBytes("Quit\r\n"));


                  sendClient.Close();


            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

有人有想法吗?

您没有告诉我们连接的另一端,所以这个答案部分是推测的...

BitConverter.GetBytes(fileNameByte.Length); 很可能是 little-endian 转换。

几乎所有网络编码都是大端编码,因此这是失败的有力候选者。

我建议您使用 Jon Skeet miscutilEndianBitConverter.Big 转换器来获得正确的编码顺序。

我使用此代码发送最大 1GB 的文件

服务器代码

    using System;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    using System.Net.Sockets;
    using System.Net;
    using System.IO;

    namespace Server_FileSend
    {
     public partial class Form1 : Form
    {
    Socket Server = null;
    Socket Client = null;
    Thread trStart;
    Thread trRecive;
    const int sizeByte = 1024;
    public Form1()
    {
        InitializeComponent();
    }
    private void ReciveFile()
    {
        while (true)
        {
            try
            {
                byte[] b = new byte[sizeByte];
                int rec = 1;
                int vp = 0;
                rec = Client.Receive(b);

                int index;
                for (index = 0; index < b.Length; index++)
                    if (b[index] == 63)
                        break;
                string[] fInfo = Encoding.UTF8.GetString(b.Take(index).ToArray()).Split(':');
                this.Invoke((MethodInvoker)delegate
                {
                    progressBar1.Maximum = int.Parse(fInfo[0]);
                });
                  string path = Application.StartupPath + "\Downloads\";
                if (!Directory.Exists(path))
                    Directory.CreateDirectory(path);
                FileStream fs = new FileStream(path + fInfo[1], FileMode.Append, FileAccess.Write);
                string strEnd;
                while (true)
                {
                    rec = Client.Receive(b);
                    vp = vp + rec;
                    strEnd = ((char)b[0]).ToString() + ((char)b[1]).ToString() + ((char)b[2]).ToString() + ((char)b[3]).ToString() + ((char)b[4]).ToString() + ((char)b[5]).ToString();
                    if (strEnd == "!endf!")
                    {
                        fs.Flush();
                        fs.Close();
                        MessageBox.Show("Receive File " + ((float)(float.Parse(fInfo[0]) / 1024)).ToString() + "  KB");
                        break;
                    }
                    fs.Write(b, 0, rec);
                    this.Invoke((MethodInvoker)delegate
                    {
                        progressBar1.Value = vp;
                    });
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                Form1_FormClosing(null, null);
            }
        }
    }
    private void StartSocket()
    {
        Server.Listen(1);
        Client = Server.Accept();
        trRecive = new Thread(new ThreadStart(ReciveFile));
        trRecive.Start();
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        Server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
        IPEndPoint IP = new IPEndPoint(IPAddress.Any, 5050);
        Server.Bind(IP);
        trStart = new Thread(new ThreadStart(StartSocket));
        trStart.Start();
    }
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        try
        {
            trRecive.Abort();
            trStart.Abort();
            Environment.Exit(Environment.ExitCode);
        }
        catch (Exception)
        {
            Environment.Exit(Environment.ExitCode);
        }
    }
   }
 }

客户代码

 using System;
 using System.IO;
 using System.Net;
 using System.Net.Sockets;
 using System.Text;
 using System.Threading;
 using System.Windows.Forms;

 namespace Clienf_fileSend
 {
  public partial class Form1 : Form
  {
    Socket Client = null;
    Thread trRecive;
    const int sizeByte = 1024;
    public Form1()
    {
        InitializeComponent();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            Client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
            IPEndPoint IP = new IPEndPoint(IPAddress.Parse(textBox1.Text), 5050);
            Client.Connect(IP);
            button1.Enabled = false;
            button2.Enabled = true;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    private void SendFile(object FName)
    {
        try
        {
            FileInfo inf = new FileInfo((string)FName);
            progressBar1.Invoke((MethodInvoker)delegate
            {
                progressBar1.Maximum = (int)inf.Length;
                progressBar1.Value = 0;
            });
            FileStream f = new FileStream((string)FName, FileMode.Open);
            byte[] fsize = Encoding.UTF8.GetBytes(inf.Length.ToString() + ":");
            byte[] fname = Encoding.UTF8.GetBytes(inf.Name + "?");
            byte[] fInfo = new byte[sizeByte];
            fsize.CopyTo(fInfo, 0);
            fname.CopyTo(fInfo, fsize.Length);
            Client.Send(fInfo);
               if (sizeByte> f.Length)
        {
            byte[] b = new byte[f.Length];
            f.Seek(0, SeekOrigin.Begin);
            f.Read(b, 0, (int)f.Length);
            Client.Send(b);
        }
        else
        {
            for (int i = 0; i < (f.Length - sizeByte); i = i + sizeByte)
            {
                byte[] b = new byte[sizeByte];
                f.Seek(i, SeekOrigin.Begin);
                f.Read(b, 0, b.Length);
                Client.Send(b);
                progressBar1.Invoke((MethodInvoker)delegate
                {
                    progressBar1.Value = i;
                });
                if (i + sizeByte >= f.Length - sizeByte)
                {
                    progressBar1.Invoke((MethodInvoker)delegate
                    {
                        progressBar1.Value = (int)f.Length;
                    });
                    int ind = (int)f.Length - (i + sizeByte);
                    byte[] ed = new byte[ind];
                    f.Seek(i + sizeByte, SeekOrigin.Begin);
                    f.Read(ed, 0, ed.Length);
                    Client.Send(ed);
                }
            }

        }
            f.Close();
            Thread.Sleep(1000);
            Client.Send(Encoding.UTF8.GetBytes("!endf!"));
            Thread.Sleep(1000);
            MessageBox.Show("Send File " + ((float)inf.Length / 1024).ToString() + "  KB");
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

    }

    private void button2_Click(object sender, EventArgs e)
    {
        OpenFileDialog fdl = new OpenFileDialog();
        if (fdl.ShowDialog() == DialogResult.OK)
        {
            trRecive = new Thread(new ParameterizedThreadStart(SendFile));
            trRecive.Start(fdl.FileName);
        }
        fdl = null;
    }
    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        try
        {
            trRecive.Abort();
            Environment.Exit(Environment.ExitCode);
        }
        catch (Exception)
        {
            Environment.Exit(Environment.ExitCode);
        }
    }
   }
 }