Одна проблема в том, что вы неправильно обрабатываете возвращаемые значения из recv()
.Например:
if (recv(Sub, Filesize, 1024, 0)) // File size
... когда функция, указанная выше, возвращает значение, она записывает некоторое количество байтов (больше 0, меньше 1025) в Filesize
.Как много?Ваша программа не знает, потому что вы не сохранили возвращаемое значение в переменной, чтобы выяснить это (скорее вы только проверили его, чтобы увидеть, было ли оно ненулевым, или нет, а затем сбросили значение).Следовательно, вполне вероятно, что Filesize
содержит не только значение размера вашего файла, но и некоторую часть данных вашего файла ... именно поэтому эта часть данных вашего файла не будет записана на диск позже в вашемprogram.
Подобная проблема здесь:
int reader = recv(Sub, Buffer, Size, 0);
Вы проверяете reader
, чтобы увидеть, является ли это -1
или 0
(что хорошо), но в вашем финалеЕсли вы просто fwrite()
из Size
байтов из массива, когда Buffer
содержит reader
байтов, а не Size
байтов (и reader
может иметь любое значение от 1
до Size
, в зависимости отсколько байтов стек TCP решил доставить вам в этом конкретном recv()
вызове.
Еще одна проблема заключается в том, что вы отправляете MAX_PATH
байтов для размера файла, но вы получаете (до) 1024 байтадля размера файла. MAX_PATH
равно 1024? Если нет, то даже если recv()
заполнило все 1024 байта, ваш отправитель и получатель все равно будут не синхронизированы друг с другом, так как избыточные байты будут отображаться вбудущие recv()
звонки или (альтернативно) вы получите байты от последующих вызовов send()
, помещенных в ваш буфер FileSize.
Так что это прямая проблема - я думаю, что основная проблема заключается в том, что вы делаете некоторые предположения о том, как работает сеть TCP, которыене правда.В частности:
Нет гарантии однозначного соответствия между send()
и recv()
вызовами.(TCP является протоколом потока байтов и не создает данных)
Вы не можете полагаться на N байтов данных от одного вызова до send()
, доставляемого черезодин звонок на recv()
.Байты, которые вы send()
, будут доставлены по порядку, но нет никаких гарантий относительно того, сколько вызовов на recv()
потребуется для их получения, а также на то, сколько байтов любой данный вызов recv()
записывает в ваш прием.-buffer.
Вы не можете полагаться на recv()
для заполнения всего буфера, который вы ему передали.recv()
запишет столько байтов, сколько захочет, и ваш код должен правильно его обрабатывать независимо от того, сколько байтов он получает за recv()
вызов.
На практике это означает, что вам нужно будет вызывать recv()
в цикле и тщательно отслеживать возвращаемое значение из каждого вызова recv()
, чтобы вы всегда точно знали, сколько байтов вы получили до сих пор и, следовательно,где внутри вашего буфера следующий recv()
вызов должен начать писать в.