Отправка более 32768 байт одновременно с одного TCP-сокета на другой - PullRequest
0 голосов
/ 08 февраля 2010

Эй, ребята, я не знаю, задавался ли этот вопрос, но представьте следующую ситуацию:

У меня есть два TCP-сокета (открываются с NSSocketPort и прослушиваются с двумя NSFileHandle), и теперь я хочу отправить NSData между ними.

@try {
    [fileHandle writeData:data];
}
@catch (NSException * e) {
    // Do some alert
}

Все в порядке, пока я не захочу отправить NSData экземпляр длиной более 32768 байт. Больше чем это число байтов не будет передано. Итак, вот мои вопросы:

1) Почему Какао не может отправлять более 32768 байт одновременно?
2) Нужно ли делать обходной путь?
3) Если да, я бы разделил данные, но как бы вы это сделали? А как другой сокет узнает, когда все данные отправлены?

Кстати, после отправки этого единственного NSData экземпляра оба сокета должны быть снова закрыты.

Ответы [ 2 ]

2 голосов
/ 08 февраля 2010

Количество данных, отправляемых за один раз, зависит от размера буфера, который используют базовые платформы и библиотеки. Хотя это может быть настраиваемым, это в основном не имеет значения. Преимущество TCP в том, что он либо гарантирует доставку ваших данных (в одном или нескольких пакетах), либо изящно дает сбой.

  1. Вам не нужно разделять свои данные перед отправкой. Базовая система сделает это за вас.
  2. На принимающей стороне вы можете прочитать доступные данные, затем подождать, пока прибудет больше байтов, обработать их и т. Д., Пока больше не будет доступных данных. Когда отправитель завершит отправку своих данных, он закроет сокет и получатель получит уведомление.
2 голосов
/ 08 февраля 2010

Ваша проблема не в какао, а в концептуальном неправильном понимании потоковых сокетов.

TCP - это потоковый протокол. Границы отдельных записей не будут сохраняться.

Если вы отправляете 32768 байтов, принимающая сторона должна быть готова к readData (или как там его называют), чтобы он возвращал куда-нибудь от одного байта до 32768 байтов. Если вы получите меньше 32768 байт, то вам нужно прочитать снова, чтобы получить остальное. Или, может быть, не все остальные, и вы должны прочитать еще раз. Вы должны разработать сетевой протокол, чтобы принимающая сторона знала, когда она получила все данные; например, префикс данных с их длиной.

Если writeData отправляет меньше данных, которые вы указали для отправки, снова вызовите writeData с остальными данными. И будьте готовы к , чтобы также отправил меньше, чем вы просили.

...