Есть два основных способа сделать это:
Используйте символ разделителя файлов и внедрите механизм «экранирования» разделителя, если он появляется в содержимом файла.
Передайте длину файла перед отправкой.
Первый подход требует, чтобы отправляющая и получающая стороны проверяли каждый байт каждого переданного файла. Второй подход лучше, потому что он избегает этого. Тем не менее, предполагается, что вы можете определить длину файла, прежде чем отправить его ... что не всегда так; например если вы генерируете файлы на лету, пишите их прямо в поток сокетов.
Существует вариант второго подхода, воплощенный в HTTP-схеме «чанк кодирования». (Спасибо @BalusC за напоминание.) Это включает в себя разбиение файла и отправку его в виде последовательности «чанков», которым предшествуют размеры чанков. Это имеет два преимущества по сравнению с подходом «размер + файл»:
- Отправителю не нужно заранее знать размер файла.
- Возможно (при подходящем дизайне протокола) отправитель или получатель могут отменить / пропустить отправку одного файла и перейти к следующему. (При простом подходе «размер + файл» протокол не может это поддерживать, поскольку отправитель и получатель не могут надежно ресинхронизироваться.)