Как записать данные в сокет в BlackBerry? - PullRequest
1 голос
/ 30 мая 2009

Я отправляю данные на сервер дважды. Сначала я отправляю «Hello world», а затем отправляю «Server». Но сервер получил данные при 1 чтении. Но сервер должен читать данные в двух операциях чтения.

Также я пишу данные. Затем прочитайте данные с сервера, а затем я записываю данные. В этом случае сервер может прочитать первые данные. Но сервер не может прочитать вторые данные. Сервер использует чтение, запись, чтение.

Так как преодолеть эту проблему? Как записать данные в сокет в BlackBerry?

Ответы [ 6 ]

2 голосов
/ 10 июня 2009

Что вы описываете, так это то, как TCP должен работать по умолчанию. То, что вы видите, - это алгоритм Нагла (RFC 896), который уменьшает количество отправляемых исходящих пакетов, чтобы они обрабатывались максимально эффективно. Возможно, вы отправляете 2 пакета в своем коде, но они передаются вместе как 1 пакет. Поскольку TCP является байтовым потоком, получатель не должен делать никаких предположений о том, сколько пакетов он получает. Вы должны разграничить свои пакетные данные в протоколе более высокого уровня, а получатель должен обработать данные в соответствии с этим протоколом. Он должен обрабатывать случаи, когда несколько пакетов поступают в одном чтении, один пакет приходит в нескольких чтениях, и все, что между ними, обрабатывает только пакетные данные, когда они получены полностью, кэшируя все, что осталось для последующих чтений, чтобы обработать, когда необходимо.

1 голос
/ 17 июля 2009

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

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

Следующий код представляет собой протокол, закодированный в строку со структурой [длина]; [данные]

StringBuffer headerStr = new StringBuffer();
StringBuffer data = new StringBuffer();
//read header
char headerByte = dataInputStream.readChar();
while (headerByte != ';') {
  headerStr.append(headerByte);
  headerByte = dataInputStream.readChar();
}
//header has the number of character to read
int header= Integer.parseInt(headerStr.toString());
int bytesReaded = 1;
char dataByte = dataInputStream.readChar();
//we should read the number of characters indicated in the header
while (bytesReaded < header) {
 data.append(dataByte);
 dataByte = dataInputStream.readChar();
 bytesReaded++;
}
1 голос
/ 01 июня 2009

Трудно сказать, не вдаваясь в подробности, но похоже, что вы используете однонаправленную связь в первом случае - т.е. клиент пишет, а затем пишет снова. Существует множество причин, по которым сервер получит 2 записи как 1 чтение. Буферизация на клиенте, где-то в беспроводном стеке (или в BES), буферизация на стороне сервера. Все они являются законными с TCP / IP.

Не зная ничего о вашем решении, задумывались ли вы об определении небольшого протокола - т.е. клиент записывает известный байт или байты (например, 0 байт?) Перед отправкой второй записи? Затем сервер может прочитать, затем распознать байт-разделитель и сказать «ага, теперь это другая запись от клиента»?

0 голосов
/ 02 января 2012

У меня есть решение, которое нужно преодолеть, чтобы извлечь обе строки

На устройстве отправителя

  • Создать заголовок, который содержит детали этих данных, например, данные длина, тип данных и т. д.
  • Добавьте этот заголовок к фактическим данным и отправьте его

На устройстве получателя

  • читать заголовок
  • получить фактическую длину данных из заголовка
  • читать следующие данные до длины данных, указанной в заголовке
0 голосов
/ 16 июня 2009

Я бы попытался явно сказать Connector.open, чтобы открыть поток как read_write. Тогда я буду следить за тем, чтобы мои соединения сбрасывались после каждого разговора с сервером.

SocketConnection connection = (SocketConnection) Connector.open(url, Connector.READ_WRITE);
OutputStream out = connection.openOutputStream();
// ... write to server
out.flush()
0 голосов
/ 30 мая 2009

Для первого запроса, я полагаю, вы используете TCP. Если вы используете UDP, то сервер будет читать пакеты в нужном вам порядке.

Можете ли вы быть более понятным / подробным по второму запросу?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...