Сокет C# получает неполные данныеC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Сокет C# получает неполные данные

Сообщение Anonymous »

Я работаю над парой приложений сервер/клиент, которые работают вместе как удаленный проводник файлов, например Filezilla.

Для связи используются TCP-сокеты, и это центральный класс обоих приложений. они используют для общения:

Код: Выделить всё

public class SocketHelper
{
public static async Task SendAsync(Socket socket, object message)
{
// Size
var sendBuffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(message));
await socket.SendAsync(BitConverter.GetBytes(sendBuffer.Length));

// Payload
var sentBytes = 0;

while (sentBytes < sendBuffer.Length)
{
sentBytes += await socket.SendAsync(sendBuffer);
}
}

public static async Task ReceiveAsync(Socket socket)
{
// Size
var preflightBuffer = new byte[32];
await socket.ReceiveAsync(preflightBuffer);

// Payload
var receiveBuffer = new byte[BitConverter.ToInt32(preflightBuffer)];
var receivedBytes = 0;

while (receivedBytes < receiveBuffer.Length)
{
receivedBytes += await socket.ReceiveAsync(receiveBuffer);
}

return Encoding.UTF8.GetString(receiveBuffer);
}
}
Как видите, сначала я отправляю размер, а затем каждый раз подсчитываю количество отправленных и полученных байтов, чтобы скоординировать и ограничить объем отправляемых и получаемых данных.
Это прекрасно работает для небольших «сообщений», таких как простые сериализованные объекты запросов/ответов для таких списков каталогов:

Код: Выделить всё

public class FolderListingRequest
{
public string Path { get; set; }
}

public class FolderListingResponse : Response
{
public IList Files { get; set; } = [];
}
Однако для больших объемов данных (загрузка файлов) он разваливается, потому что где-то во время передачи сообщения приходят либо неполными, либо с дополнительными данными в конце, что приводит к сбою десериализации.
/>
Более того, он совершенно непоследователен в случае сбоя. Иногда отправка 5 файлов за один раз работает нормально, но иногда она прерывается при отправке одного файла.
Вот код сервера, который запрашивает и обрабатывает загрузку файлов:

Код: Выделить всё

public async Task DownloadFiles(Socket socket, DownloadFilesRequest request)
{
var payload = new Payload
{
Type = PayloadTypeEnum.DownloadFiles,
Data = request,
};
var fileCountToReceive = request.Paths.Count;
var fileCountReceived = 0;
await SocketHelper.SendAsync(socket, payload);

while (fileCountReceived < fileCountToReceive)
{
Console.WriteLine("Receiving file");
var receivedData = await SocketHelper.ReceiveAsync(socket);
var fileData = JsonConvert.DeserializeObject(receivedData);

if (fileData == null)
{
Console.WriteLine("Could not deserialize downloaded file info");
}

localFileService.StoreFile(fileData);
fileCountReceived++;
}
}
А вот клиентская часть, которая отправляет файлы:

Код: Выделить всё

public async Task SendFiles(Socket socket, DownloadFilesRequest request)
{
foreach (var path in request.Paths)
{
var response = new FileData()
{
Path = path,
Contents = localFileService.GetFileContents(path),
};

await SocketHelper.SendAsync(socket, response);
}
}
Возможно ли, что это какая-то проблема синхронизации, когда клиент отправляет больше данных, чем предназначен для приема сервером? Разве подсчета байтов не должно быть достаточно, чтобы облегчить это? Должен ли я вместо этого использовать маркеры для начала и конца сообщений?
Или я пытаюсь отправить слишком много данных за раз? Стоит ли мне это разбить?
Есть мысли?

Подробнее здесь: https://stackoverflow.com/questions/787 ... plete-data
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Неверные или неполные данные хранилища сборок после переупаковки AAB.
    Anonymous » » в форуме Android
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous
  • Функция RasenumConnections в JNA возвращает неполные данные. Что я делаю не так?
    Anonymous » » в форуме JAVA
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Как разрешить странные и неполные Uri и Path, полученные при прямой передаче изображения из галереи Android в мое прилож
    Anonymous » » в форуме Android
    0 Ответы
    25 Просмотры
    Последнее сообщение Anonymous
  • Вернуть только неполные элементы Todo List
    Anonymous » » в форуме C#
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • Как обнаружить неполные задания печати в Android?
    Anonymous » » в форуме Android
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»