Отправка более 32768 байт одновременно с одного TCP-сокета на другой
Эй, ребята, я не знаю, задавался ли этот вопрос, но представьте следующую ситуацию:
У меня есть два TCP-сокета (открывается с NSSocketPort
и слушать с двумя NSFileHandle
) и теперь я хочу отправить некоторые NSData
между ними.
@try {
[fileHandle writeData:data];
}
@catch (NSException * e) {
// Do some alert
}
Все правильно, пока я не хочу отправить NSData
экземпляр длиной более 32768 байт. Больше чем это количество байтов не будет передано. Итак, вот мои вопросы:
1) Почему Какао не может отправлять более 32768 байт одновременно?
2) я должен сделать обходной путь?
3) Если да, я бы разделил данные, но как бы вы это сделали? И как другой сокет узнает, когда все данные отправлены?
Кстати, после отправки этого сингла NSData
Экземпляр обоих сокетов должен быть снова закрыт.
2 ответа
Объем данных, отправляемых за один раз, зависит от размера буфера, используемого базовыми платформами и библиотеками. Хотя это может быть настраиваемым, это в основном не имеет значения. Преимущество TCP в том, что он либо гарантирует доставку ваших данных (в одном или нескольких пакетах), либо изящно дает сбой.
- Вам не нужно разделять свои данные перед отправкой. Базовая система сделает это за вас.
- На принимающей стороне вы можете прочитать доступные данные, затем подождать, пока прибудет больше байтов, обработать их и т. Д., Пока больше не будет доступных данных. Когда отправитель завершит отправку своих данных, он закроет сокет и получатель получит уведомление.
Ваша проблема не в какао, а в концептуальном неправильном понимании потоковых сокетов.
TCP - это потоковый протокол. Границы отдельных записей не будут сохранены.
Если вы отправляете 32768 байт, принимающая сторона должна быть готова к readData (или как там его называют), чтобы он возвращался в любом месте от одного байта до 32768 байт. Если вы получите меньше 32768 байт, то вам нужно прочитать снова, чтобы получить остальное. Или, может быть, не все остальное, и вам придется читать еще раз. Вы должны спроектировать свой сетевой протокол, чтобы принимающая сторона знала, когда она получила все данные; например, префикс данных с их длиной.
Если writeData отправляет меньше данных, которые вы указали для отправки, снова вызовите writeData с остальными данными. И будьте готовы к тому, чтобы отправлять меньше, чем вы просили.