Socket.Avaliable потеря C # - PullRequest
0 голосов
/ 28 мая 2018

Я написал этот метод, используя сокет UDP с ReceiveTimeout = 1000. И иногда он теряет второй пакет:

private static byte[] ReceivePlainData(Socket socket) {
    var recievedData = new List<byte>();
    var buffer = new byte[1024];

    do {
        int recievedAmount;

        while (true) {
            try {
                recievedAmount = socket.Receive(buffer);
            }
            catch (SocketException) {
                continue;
            }

            break;
        }

        recievedData.AddRange(buffer.Take(recievedAmount));
    } while (socket.Available > 0);

    return recievedData.ToArray();
}

Инициализация сокета:

using (var socket = new Socket(SocketType.Dgram, ProtocolType.Udp) {
    ReceiveTimeout = 1000
})

Что мне нужно изменить назаставить этот метод работать правильно?

1 Ответ

0 голосов
/ 28 мая 2018

Socket.Available только сообщает вам, если данные были получены и доступны для немедленного чтения.Он не говорит вам, завершен ли поток или нет.Отправитель может все еще находиться в процессе генерации или передачи большего количества данных.Если вы намереваетесь использовать весь ответ и рассчитываете, что отправитель закроет сокет, когда данных больше нет, продолжайте чтение из сокета до тех пор, пока число возвращаемых байтов не станет равным 0 (указывая, что сокет был закрыт нормально), иливозникает исключение (указывает на ненормальное завершение).

MemoryStream stream = new MemoryStream();
int received;
var buffer = new byte[8096];

do {
    received = socket.Receive(buffer);
    stream.Write(buffer, 0, received);
} while (received > 0);

// Use the stream
// byte[] bytes = stream.ToArray();

Установите для сокета ReceiveTimeout максимальное количество времени, которое вы готовы подождать между байтами перед прерыванием.

...