/ / boost asio confusão de nova linha de plataforma cruzada - c ++, newline, boost-asio

impulsionar asio cross platform newline confusão - c ++, newline, boost-asio

Estou usando o boost asio para escrever um servidor / cliente simples para transmitir dados binários. Particularmente, estou usando async_write e async_read com ip: tcp :: socket. Nada extravagante, realmente.

boost::asio::async_write(*mp_socket, boost::asio::buffer(data_ptr, data_size),
boost::bind(&TcpSocket::m_handleWrite, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));

boost::asio::async_read(*mp_socket, boost::asio::buffer(mp_buffer, m_buffer_size),
boost::bind(&TcpSocket::m_handleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));

Gerei dados binários aleatoriamente e enviei / recebi em vários pares de plataformas para testar. O código funciona bem na mesma plataforma (como todos no linux, todos no windows), mas falha ao funcionar em várias plataformas.

Por exemplo, à esquerda são recebidos dados emjanelas e à direita são enviados dados no linux. A única diferença é 0D0A (CRLF) no Windows e 0A (LF) no Linux. Eu acho que em algum lugar (no boost asio, ou winsock, etc.), a conversão LF-> CRLF está acontecendo.

Portanto, existe uma maneira de desativar a conversão, poisEstou enviando dados binários? Eu estava procurando por alguma opção na configuração boost :: asio (como usar buffer bruto, não buffer de fluxo), mas não consegui encontrá-lo. Obrigado pela ajuda.

insira a descrição da imagem aqui


dados em data_ptr

  size_t sz = rand() % 60000;
char* p = (char*)malloc(sz + 4);
uint32_t* p_header = reinterpret_cast<uint32_t*>(p);
*p_header = htonl((uint32_t)sz);
for (size_t i = 0; i < sz; ++i)
{
p[i + 4] = rand() % 255;
}

Respostas:

0 para resposta № 1

Eu acho que a questão é porque async_read é "orientado a fluxo", consulte: Leituras e gravações curtas.

Eu assumo isso asio está usando CRLF ou LF como terminadores de fluxo no Windows e Linux, respectivamente, e acho que em algum lugar ele está usando um terminador do Windows para um fluxo do Linux ou vice-versa.

Tente mudar o seu async_read ligar para:

mp_socket->async_read_some(boost::asio::buffer(mp_buffer, m_buffer_size),
boost::bind(&TcpSocket::m_handleRead, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));

Eu usei esse método para ler arquivos binários grandes e verifiquei os arquivos recebidos com o hash deles, sem nenhum dos problemas que você encontrou.