Member 12359828 Ответов: 1

Проблема в получении файла с socket-C#


Привет,
Я пытаюсь отправить файл через сокет с сервера на клиент ( im использует обратный метод подключения )
Итак вот мои шаги:
0-отправить запрос на загрузку клиенту
Файл 1-значение длины + именем
2-отправить детали клиенту
3-клиент создаст байтовый массив с вычисленной длиной
3-чтение файла с сервера в байтовый массив
4-отправить байт с помощью socket. send(byte, 0, byte.длина,socketflag.нет)

Но проблема в том, что когда я получаю "файл, полученный" от клиента, мой файл сломан.
Как я могу это исправить?

Что я уже пробовал:

Метод ReceiveInfo () предназначен для работы на стороне клиента
static private void ReceiveInfo() //Client receving data check if its a normal command or request to download a file
            {
                byte[] buffer = new byte[1024];
                int received = 0;

                try
                {
                    received = ClientSocket.Receive(buffer);
                }
                catch (SocketException)
                {
                    //
                }

                if (received == 0)
                    return;

                byte[] data = new byte[received];
                System.Array.Copy(buffer, data, received);

                if(IsDownload)
                {
                    DownloadCommand(data);
                }

                else
                {
                    NormalCommand(data);
                }

            }


когда я отправлю запрос на загрузку, флаг IsDownload изменится на true.
Вот Шаг 3: (Когда клиент получает запрос на загрузку)
string[] info = // it contains details of file
FileName = info[1];
FileSize = int.Parse(info[2]);
FileBytes = new byte[FileSize];
IsDownload = true;


Клиент получает информацию, создает байтовый массив и ждет, когда сервер отправит данные.

public static void DownloadCommand(byte[] data)
            {


                    Buffer.BlockCopy(data, 0, FileBytes, WriteSize, data.Length);

                    WriteSize += data.Length;


                if (FileBytes.Length == FileSize)
                {
                    try
                    {
                        using (FileStream fs = File.Create(FileName))
                        {
                            byte[] info = FileBytes;
                            fs.Write(info, 0, info.Length);
                        }

                        Array.Clear(FileBytes, 0, FileBytes.Length);
                    }
                    catch (Exception ex)
                    {

                    }
                    SendData("File Received.");
                    IsDownload = false;
                    WriteSize = 0;
                }
            }


А вот и серверные коды:

public static void SendFile(Socket s, string fileName)
            {
                try
                {
                    if (s.Connected)
                    {
                        TargetClient = s;
                        byte[] dataToSend = File.ReadAllBytes(fileName);
                        string fileInfo = Path.GetFileName(fileName) + "~" + dataToSend.Length;
                        SendCommand("IsDownload~" + fileInfo);
                        TargetClient.Send(dataToSend,0,dataToSend.Length,SocketFlags.None);
                    }

                }

                catch (Exception ex)
                {
                    LogManager.SetLog("Error in SendFile(Socket,string):\n" + ex.Message);
                };

            }

1 Ответов

Рейтинг:
2

RickZeeland

Вам не хватает цикла в вашей функции приема, это означает, что вы получаете только первые 1024 байта файла.
См. пример здесь: Socket Send and Receive [C#][^]
а здесь: Работа с сокетами в C#[^]
Альтернативой является использование WebClient(), что делает вещи намного проще: [https://www.dotnetperls.com/webclient]