Как отправить файл по сокетам по протоколу TCP в C #? - PullRequest
0 голосов
/ 31 января 2019

У меня серьезная проблема с этим кодом.Вот как это должно работать: клиент подключается к серверу и выбирает файл на диске.после этого клиент отправляет (byte [] буфер) на сервер этим форматом («Файл» (4 байта) + FileNameLength (4 байта) + FileDataLength (4 байта)).После этого сервер создает (byte [] буфер) с этим размером (новый байт [FileNameLength + FileDataLength]). Таким образом, клиент отправляет данные на сервер в этом формате (byte [] buffer = FileName + FileData).И сервер получает файл.Проблема здесь в том, что у меня есть MessageBox на сервере, чтобы увидеть FileName после его получения, но MessageBox всегда пуст и работает раз и раз, и раз.в чем решение?

Сервер:

    private Socket SServer = null;
    private Socket SClient = null;
    private byte[] buffer = new byte[1024];
    private byte[] FileNameLength = null;
    private byte[] FileSize = null;

    private void Server_Load(object sender, EventArgs e)
    {
        SServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        SServer.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13000));
        SServer.Listen(1);
        new Thread(() =>
        {
            SClient = SServer.Accept();
            MessageBox.Show("Connected.");
            new Thread(() => Receiver()).Start();
        }).Start();
    }

    private void Receiver()
    {
        buffer = new byte[1024];
        while (true)
        {
            Int32 AllLength = SClient.Receive(buffer, 0, buffer.Length, SocketFlags.None);
            byte[] Devider = new byte[4];
            Array.Copy(buffer, 0, Devider, 0, 4);
            string Devide = Encoding.ASCII.GetString(Devider);
            if (AllLength > 0)
            {
                if (Devide == "File")
                {
                    FileNameLength = new byte[4];
                    Array.Copy(buffer, 4, FileNameLength, 0, 4);
                    FileSize = new byte[4];
                    Array.Copy(buffer, 8, FileSize, 0, 4);
                    buffer = null;
                    buffer = new byte[BitConverter.ToInt32(FileNameLength, 0) + BitConverter.ToInt32(FileSize, 0)];
                }
                else
                {
                    byte[] FileNameBytes = new byte[BitConverter.ToInt32(FileNameLength, 0)];
                    Array.Copy(buffer, 0, FileNameBytes, 0, BitConverter.ToInt32(FileNameLength, 0));
                    byte[] FileBytes = new byte[BitConverter.ToInt32(FileSize, 0)];
                    Array.Copy(buffer, BitConverter.ToInt32(FileNameLength, 0), FileBytes, 0, BitConverter.ToInt32(FileBytes, 0));
                    string FileName = Encoding.ASCII.GetString(FileNameBytes);
                    MessageBox.Show(FileName);
                    buffer = null;
                    buffer = new byte[1024];
                }
            }
        }
    }

TheClient:

    private Socket SClient = null;
    string Path, FileName;

    private void Client_Load(object sender, EventArgs e)
    {
        SClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        SClient.Connect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 13000));
    }

    private void BT_SendFile_Click(object sender, EventArgs e)
    {
        byte[] FileLengthBytes = BitConverter.GetBytes(FileName.Length);
        byte[] FileBytes = File.ReadAllBytes(Path + FileName);
        byte[] buffer = new byte[FileLengthBytes.Length + FileBytes.Length + 4];
        //buffer = Encoding.Unicode.GetBytes("File") + FileLengthBytes + FileBytes;
        Array.Copy(Encoding.ASCII.GetBytes("File"), 0, buffer, 0, 4);
        Array.Copy(FileLengthBytes, 0, buffer, 4, FileLengthBytes.Length);
        Array.Copy(BitConverter.GetBytes(FileBytes.Length), 0, buffer, 8, 4);
        SClient.Send(buffer, 0, buffer.Length, SocketFlags.None);
        byte[] FileNameBytes = Encoding.ASCII.GetBytes(FileName);
        buffer = null;
        buffer = new byte[FileNameBytes.Length + FileBytes.Length];
        Array.Copy(FileNameBytes, 0, buffer, 0, FileNameBytes.Length);
        Array.Copy(FileBytes, 0, buffer, FileNameBytes.Length, FileBytes.Length);
        SClient.Send(buffer, 0, buffer.Length, SocketFlags.None);
    }

    private void BT_Browse_Click(object sender, EventArgs e)
    {
        OpenFileDialog N = new OpenFileDialog();
        if (N.ShowDialog() == DialogResult.OK)
        {
            TB_Address.Text = N.FileName;
            string[] Seperate = N.FileName.Split('\\');
            FileName = Seperate[Seperate.Length - 1];
            Path = null;
            foreach (string str in Seperate)
            {
                if (str != Seperate[Seperate.Length - 1])
                    Path += str + "\\";
            }
        }
    }

1 Ответ

0 голосов
/ 31 января 2019

Как сказал этот друг ( Fildor ), я пытаюсь прочитать больше о протоколах.Спасибо, ребята, но я думаю, что если я отделю файл и пошлю его по частям, я могу отправить файл с дырой.Я знаю, может быть, это глупо, но я думаю, что это работает.

...