Наиболее типичный способ сделать это состоит в том, чтобы первые несколько байтов блока данных были длиной фрагмента.
Так, например, если размер вашего объекта всегда меньше 65k илитам вы можете отправить размер массива через сокет первым как короткий (посмотрите на использование класса BitConverter).Получатель считывает первый полученный блок в буфер (вероятно, примерно размером с номинальный пакет UDP, где-то около 512 байт), захватывает первые два байта, преобразует их в короткий и устанавливает буфер для объекта.,Затем он продолжит чтение из сокета, пока этот буфер не заполнится, и передаст этот буфер десериализатору.
Это, конечно, не распространяется на обработку ошибок и тому подобное, но это основная идея.
РЕДАКТИРОВАТЬ:
Прошло некоторое время, так как я сделал что-то с UDP в .Net, но что-то вроде этого может работать (в несколько psuedocode)
var bigBuffer = new MemoryStream();
//This should be run in a thread
void UdpLoop()
{
while(!done)
{
var buffer = udpClient.Receive();
bigBuffer.Write(buffer,buffer.Length);
}
}
void MessageProcessor()
{
var messageLength = 0;
while(!done)
{
if(bigBuffer.Length > 0 && messageLength == 0)
{
var lengthBytes = new byte[2];
bigBuffer.Read(lengthBytes, 2);
messageLength = BitConverter.ToInt16(lengthBytes);
}
if(messageLength > 0 && bigBuffer.Length > messageLength)
{
var objectBuffer = new byte[messageLength];
bigBuffer.Read(objectBuffer, messageLength);
//Do deserialization here
}
}
}
Это основнойпроцесс, игнорируя блокировку из-за нескольких потоков (с которыми вам придется иметь дело после получения блоков получения), и чтение и запись из разных мест в потоке памяти.Надеюсь, этого достаточно, чтобы вы пошли в правильном направлении.