TCP на C# передача файлов

Рейтинг: 0Ответов: 1Опубликовано: 02.05.2023

возникала проблема разрыва соединения которое я не знаю каким образом разрывается учитывая что в серверном коде что в клиентском нет не одной строки закрытия подключения. Когда клиент заходит в метод GetCommandHandler на стороне сервера пишет такую ошибку: Ошибка при обработке соединения: The operation is not allowed on non-connected sockets. Подскажите как это можно исправить. введите сюда описание изображения Код сервера и клиента:

public class Server
    {
        private TcpListener server;
        private readonly IPAddress ServerIP;
        private readonly int ServerPort;

        public Server(string ServerIP, int ServerPort)
        {
            this.ServerIP = IPAddress.Parse(ServerIP);
            this.ServerPort = ServerPort;
        }

        public void Start()
        {
            server = new TcpListener(ServerIP, ServerPort);

            server.Start();
            Console.WriteLine("Сервер запущен и ожидает подключения клиентов");

            while (true)
            {
                TcpClient client = server.AcceptTcpClient();

                Console.WriteLine("Клиент подключился");
                Task.Factory.StartNew(() => HandleConnection(client));
            }
        }

        public static async Task<string> ReadClientMessage(TcpClient client)
        {
            using (NetworkStream stream = client.GetStream())
            {
                while (true)
                {
                    if (stream.DataAvailable)
                    {
                        Console.WriteLine("Какие-то данные появились");
                        byte[] buffer = new byte[1024];
                        int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);

                        return Encoding.UTF8.GetString(buffer, 0, bytesRead);
                    }
                }
            }
        }

        private async void HandleConnection(TcpClient client)
        {
            try
            {
                NetworkStream stream = client.GetStream();

                while (true)
                {
                    ICommand commandHandler = (ICommand)await GetCommandHandler(client);
                    await commandHandler?.Execute(stream);

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Ошибка при обработке соединения: {ex.Message}");
            }
            finally
            {
                client?.Close();
            }
        }
        private async Task<ICommand> GetCommandHandler(TcpClient client)
        {
            string command = await ReadClientMessage(client);
            Console.WriteLine(command);
            Console.WriteLine(client.Connected ? "Клиент подключен" : "Клиент отключился");
            
                switch (command)
                {
                    case "$download":

                        string SendPath = await ReadClientMessage(client);
                        Console.WriteLine($"Сервер получил путь для отправки файла - {SendPath}");

                        if (File.Exists(SendPath))
                        {
                            return new UploadCommand(SendPath);
                        }
                        else
                        {
                            Console.WriteLine($"Путь для отправки клиенту некорректен - {SendPath}");
                        }

                        break;

                    case "$upload":

                        string SavePath = await ReadClientMessage(client);
                        Console.WriteLine($"Сервер получил путь для сохранения файла - {SavePath}");

                        if (Directory.Exists(SavePath))
                        {
                            return new DownloadCommand(SavePath);
                        }
                        else
                        {
                            Console.WriteLine($"Путь для получения файла от клиента некорректен - {SavePath}");
                        }

                        break;
                    default:
                        Console.WriteLine($"Неизвестная команда: {command}");
                        return null;
                }

            return null;
        }  
    }

Код клиента:

    public class Client
    {
        private readonly IPAddress ipClient;
        private readonly int portClient;

        public Client(IPAddress iPAddress, int portClient)
        {
            this.ipClient = iPAddress;
            this.portClient = portClient;
        }

        public async Task Connect()
        {
            Console.Out.WriteLine("Клиент запускается...");

            TcpClient client = new TcpClient(ipClient.ToString(), portClient);
            Console.WriteLine($"Подключен к серверу");

            while (true)
            {
                Console.Write("Введите команду ($download/$upload): ");
                string command = Console.ReadLine();

                if(client.Connected)
                {
                    ICommand commandHandler = await GetCommandHandler(command, client);
                    await commandHandler?.Execute(client.GetStream());
                }
            }
        }

        public static async Task SendClientMessage(TcpClient client, string message)
        {
            byte[] buffer = Encoding.UTF8.GetBytes(message);
            NetworkStream stream = client.GetStream();
            await stream.WriteAsync(buffer, 0, buffer.Length);
        }

        private async Task<ICommand> GetCommandHandler(string command, TcpClient client)
        {
            await SendClientMessage(client, command);

            switch (command)
            {
                case "$download":
                    Console.WriteLine("Использование: <Путь для сохранения> | <Путь для извлечения>");

                    string tempDownload = Console.ReadLine();
                    string[] PathsDownload = tempDownload.Split('|');

                    Console.WriteLine($"Путь сохранения - {PathsDownload[0]}, путь отправки на сервер - {PathsDownload[1]}");

                    if (Directory.Exists(PathsDownload[0]))
                    {
                        await SendClientMessage(client, PathsDownload[1]);
                        return new DownloadCommand(PathsDownload[0]);
                    }
                    else
                    {
                        Console.WriteLine($"Путь для сохранения некорректен - {PathsDownload[0]}");
                    }
                    break;

                case "$upload":

                    Console.WriteLine("Использование: <Путь для отправки> | <Путь для сохранения>");

                    string tempUpload = Console.ReadLine();
                    string[] PathsUpload = tempUpload.Split('|');

                    Console.WriteLine($"Путь отправки на сервер - {PathsUpload[0]}, путь для сохранения - {PathsUpload[1]}");

                    if (File.Exists(PathsUpload[0]))
                    {
                        await SendClientMessage(client, PathsUpload[1]);
                        return new UploadCommand(PathsUpload[0]);
                    }
                    else
                    {
                        Console.WriteLine($"Путь для отправки некорректен - {PathsUpload[0]}");
                    }

                    break;

                default:
                    Console.WriteLine($"Неизвестная команда: {command}");
                    return null;
            }

            return null;
        }
    }

Ответы

▲ 0

Проблема была в using при получении данных от клиента в методе ReadClientMessage