Pergunta

Ao ler dados através da rede, você especificar um buffer para receber os dados em:

byte[] b = new byte[4096];
socket.Receive(b);

Agora, meu primeiro pensamento é, naturalmente, para reutilizar o buffer de recepção, declarando-o como uma variável membro da classe. Minha próxima questão é que eu não tenha recebido todos os dados que eu estou esperando, então eu preciso para amortecer os meus dados. Isto é fácil de realizar, mantendo o controle da contagem de bytes recebidos, e especificando o deslocamento:

socket.Receive(m_ReceiveBuffer, count, m_ReceiveBuffer.Length - count);

Agora, a questão aqui é que, se ele ainda não é suficiente, eu estou supondo que eu preciso para crescer o buffer, o que significa copiar a memória, e continuar a receber a este tampão. Supondo que algo deu errado, este tampão iria continuar a crescer, e se as mensagens suficientes grandes são recebidos, correria o sistema sem memória.

Todas as idéias como lidar com isso corretamente? Existe uma melhor maneira de receber os dados de apenas preenchimento, copiar, crescer, preenchimento, copiar, crescer que estou falando?

Foi útil?

Solução

lido em pedaços:

const int ChunkSize = 4096;
int bytesRead;
byte[] buffer = new byte[ChunkSize];
while ((bytesRead = socket.Receive(buffer, 0, ChunkSize, SocketFlags.None)) > 0)
{
    byte[] actualBytesRead = new byte[bytesRead];
    Buffer.BlockCopy(buffer, 0, actualBytesRead, 0, bytesRead);
    // Do something with actualBytesRead, 
    // maybe add it to a list or write it to a stream somewhere
}

Outras dicas

Antes de começar com System.Net.Sockets.Socket, você tem certeza que você não pode usar System.Net.Sockets.TcpClient (ou UdpClient) que faz todo o trabalho tampão confuso para você e transforma-lo a uma fácil gestão Stream?

Se não, lembre-se que a quantidade de dados que você recebe não tem de ser igual ao que você solicitar, por isso você deve sempre olhar para o valor de retorno da função recieve. E, a única maneira de não ficar sem memória é por realmente processando o que você recebe.

Em primeiro lugar, separar o código em que recebe os dados e processar os dados. O buffer de recepção só deve conter os dados até que o código tem a chance de copiá-lo para a área de processamento. A área de processamento é onde você vai determinar se você tiver recebido dados suficientes para fazer algo útil. Não deixe os dados na rede buffer de recebimento até que isso aconteça. Para a rede de buffer de recepção, acho que usando um buffer circular irá ajudá-lo com a sua ideia de reutilizar um buffer. Felizmente, você tem uma idéia dos tamanhos das mensagens. Isso vai ajudar a determinar o tamanho do buffer. Se você afirmar (ou algo similar) quando a ler e escrever ponteiros do buffer circular se encontram, em seguida, aumentar o tamanho do buffer. Uma vez que o tamanho do buffer é grande o suficiente, você deve ser capaz de ler dados suficientes fora do buffer no código de processamento em um ritmo rápido o suficiente para que o buffer circular não transborde.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top