Отсутствуют данные после 512-го символа при чтении из сокета (сервер С#, клиент С++)

введите здесь описание изображения

Клиент получил:

введите здесь описание изображения

Это происходит каждый раз, когда сервер отправляет более 512 байтов (т.е. символов). все после 511-го символа отсутствует.

Как я получаю:

boost::asio::streambuf receiveBuffer;
int bytesRead = boost::asio::read_until(m_socket, receiveBuffer, ';', err);

std::string data = boost::asio::buffer_cast<const char*>(receiveBuffer.data());

Как я отправляю (это на С#):

private static void Send(Socket handler, String data, StateObject state)
{
    state.WriteDone.WaitOne();

    // Add delimiter.
    data += ';'; 
    
    byte[] byteData = Encoding.ASCII.GetBytes(data);
    Console.WriteLine(data);

    handler.BeginSend(byteData, 0, byteData.Length, 0,
        new AsyncCallback(SendCallback),
        state);
}

private static void SendCallback(IAsyncResult ar)
{
    try
    {
        StateObject state = (StateObject)ar.AsyncState;

        // Complete sending the data to the remote device.  
        int bytesSent = state.WorkSocket.EndSend(ar);
        state.WriteDone.Set();

        Console.WriteLine("Sent {0} bytes to client.", bytesSent);
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
    }
}

Почему все после 511-го отсутствует? В чем проблема?

ПРИМЕЧАНИЕ. Проблема заключается не только в том, что при добавлении не получен разделитель ;. Если я попытаюсь увеличить сообщение, остальная часть сообщения (все после 512-го символа) будет потеряна.

Я думаю, что сервер отправляет данные в нескольких сегментах (каждый сегмент 512 байт). Поскольку сервер является асинхронным, после отправки первого незавершенного сегмента к потоку добавляется другой сегмент, а не остальная часть предыдущего. Как видите, я использовал AutoResetEvent WriteDone для синхронизации записи, но, похоже, это не работает.

Есть ли способ увеличить размер сегмента? (Это может просто решить проблему, однако, если снова размер сообщений увеличивается, размер сегмента также должен расти, поэтому это может быть не очень хорошим решением).

Если требуется больше кода или информации, пожалуйста, спросите в комментариях. Спасибо.

Обновлять

Приложение работало на другой машине!

Я нашел остальную часть сообщения. Он прибывает перед первой частью:

введите здесь описание изображения


person Abraham    schedule 04.10.2020    source источник
comment
Что read_until возвращает? Каково значение bytesRead?   -  person Some programmer dude    schedule 04.10.2020
comment
@Someprogrammerdude bytesRead равен 1017.   -  person Abraham    schedule 04.10.2020
comment
что вы используете для отправки данных? Вы уверены, что он правильно отправляет более 512 байт?   -  person kmdreko    schedule 04.10.2020
comment
@kmdreko Только что добавил мой код отправки. Проблема скорее всего в сервере?   -  person Abraham    schedule 04.10.2020
comment
Вы уверены, что речь идет о 512-м символе, а не о том, что boost::asio::read_until читается пока не достигает разделителя (в данном случае ';'), то есть не включено? Если вы read_until и разграничите '}', он не будет содержать '}'.   -  person Fureeish    schedule 04.10.2020
comment
@Fureeish С небольшими сообщениями все работает отлично. проблема началась, когда я увеличил размер сообщений.   -  person Abraham    schedule 04.10.2020


Ответы (1)


Вы читаете до разделителя ; в поток:

Функция read_until — это составная операция, которая считывает данные в последовательность динамического буфера.

Кажется, последовательность буфера составляет 512 байтов каждая. Попробуйте прочитать из возвращенного потока вместо получения данных.

basic_streambuf::данные

Получите список буферов, который представляет входную последовательность.

const_buffers_type data() const;

Или, лучше, прочитайте строку, поскольку это, очевидно, то, что вы хотите.

Из документов по повышению:

std::string data;
std::size_t n = boost::asio::read_until(s,boost::asio::dynamic_buffer(data), ';');
std::string line = data.substr(0, n);

Чтобы прочитать из потока:

boost::asio::streambuf receiveBuffer;
int bytesRead = boost::asio::read_until(m_socket, receiveBuffer, ';', err);

std::istream response_stream(&receiveBuffer);
std::string value;
response_stream >> value;

Но теперь я сомневаюсь, что это проблема.

Проверьте отправленные данные от C#, поскольку я предполагаю, что проблема связана с самими данными, а не с коммуникацией.

Если функция чтения возвращает 1017 в качестве возврата, она не находит ; в 513, поэтому, вероятно, она не приходит. Остальные данные выглядят нормально, поэтому кажется, что сторона C# не добавляет ;.

Попробуйте зарегистрировать массив байтов, который вы отправляете, чтобы увидеть, есть ли там точка с запятой.

person Manuel    schedule 04.10.2020
comment
Спасибо, Можете ли вы опубликовать код. Это мое первое приложение на С++, поэтому я не знаю, как читать из потока вместо получения данных, а read_until не получает строку вместо streambuf. - person Abraham; 04.10.2020
comment
@H.Ebr Если вы не умеете читать из потока, вам следует купить книгу или пройти онлайн-учебник по C ++. Это основное. - person Manuel; 04.10.2020
comment
Проблема не только в добавлении ;. Если я попытаюсь увеличить сообщение, остальная часть сообщения (все после 512-го символа) также будет потеряна. - person Abraham; 04.10.2020
comment
В вашем захвате кажется следующее сообщение. - person Manuel; 05.10.2020