Вы не можете просто ожидать одновременной записи всего файла в сокет, а также не можете рассчитывать на чтение файла из сокета за одну операцию.API-интерфейсы чтения и записи сокетов практически для любого API-интерфейса сетевого программирования, от BSD-сокетов до классов WinSock и .NET, будут передавать или получать данные до желаемого количества байтов.
Если вы посмотрите на документацию для PHP socket_write, например:
Возвращает количество байтов, успешно записанных в сокет, или FALSE при ошибке.Код ошибки можно получить с помощью socket_last_error ().Этот код может быть передан в socket_strerror () для получения текстового объяснения ошибки.
Примечание. Для socket_write () вполне допустимо возвращать ноль, что означает, что ни одного байта не было записано.Обязательно используйте оператор == для проверки на ЛОЖЬ в случае ошибки.
Как правило, вы хотите выбрать размер блока, например 4096 или 16384, и циклически передавать или принимать этот размер блока, пока выполучить желаемое количество переданных или полученных байтов.Ваш код должен проверить возвращаемое значение функции отправки или получения, которую вы вызываете, и соответствующим образом настроить указатель файла.Если при передаче возвращается 0, это может означать, что буфер отправки заполнен (не фатально), поэтому продолжайте отправку (может потребоваться задержка отключения (0)).Если при получении возвращается 0, это обычно означает, что другая сторона полностью закрыла соединение.
Один из самых критических недостатков в использовании простого сетевого кода заключается в том, что вы не отправляете размер файла перед отправкой.данные файла, поэтому получатель не может узнать, сколько нужно прочитать, прежде чем отправлять свой ответ.Для такой простой операции, как эта, я бы предложил просто отправить двоичное 32-битное целое число (4 байта).Это будет частью схемы для вашей операции.Таким образом, получатель должен сначала прочитать 4 байта, и из этого узнать, сколько еще байтов нужно прочитать (один размер буфера за раз).Приемник продолжает читать, пока у него не будет столько байтов.
Надеюсь, это поможет.Было бы замечательно, если бы код сокета был таким же простым, как и попытка использования, но, к сожалению, это не так.Вы должны выбрать размер буфера, а затем продолжать чтение или запись буферов такого размера, пока не получите желаемое, и вам не придется передавать другой стороне, какой объем данных вы планируете отправить.