TCP на C# передача файлов
возникала проблема разрыва соединения которое я не знаю каким образом разрывается учитывая что в серверном коде что в клиентском нет не одной строки закрытия подключения. Когда клиент заходит в метод 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;
}
}
Источник: Stack Overflow на русском