Вопрос

У меня есть Java-клиент, который отправляет строки UTF-8 на C # TCP-сервер, я использую DataOutputStream для отправки строк.Код выглядит примерно так:

public void sendUTF8String(String ar) {
    if (socket.isConnected()) {
        try {
            dataOutputStream.write(ar.getBytes(Charset.forName("UTF-8")));
            dataOutputStream.flush();
        } catch (IOException e) {
            handleException(e);
        }
    }
}

Проблема в том, что флеш, похоже, работает неправильно.Если я отправляю две строки близко друг к другу, сервер получает только одно сообщение с обеими строками.Все это работает, если я выполняю Thread.sleep (1000) между вызовами, это, очевидно, не решение.Что я упускаю из виду?

Это было полезно?

Решение

flush() не гарантирует, что пакет данных будет отправлен.Ваш стек TCP / IP может свободно объединять ваши данные для достижения максимальной эффективности.Хуже того, вероятно, между вами и вашим пунктом назначения есть множество других стеков TCP / IP, и они могут свободно делать то же самое.

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

Другие советы

Вам не следует беспокоиться о том, как данные разбиваются на пакеты.

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

byte[] arbytes = ar.getBytes(Charset.forName("UTF-8"));
output.writeInt(arbytes.length)
output.write(arbytes)

и затем в своем ридере вы делаете

byte[] arbytes = new byte[input.readInt()];
for(int i = 0; i < len; i++){
     arbytes[i] = input.read();
}
//convert bytes back to string.

Вы не можете просто вызвать input.read(arbytes), потому что функция read не обязательно считывает всю длину массива.Вы можете выполнить цикл, в котором вы читаете фрагмент за раз, но код для этого немного сложнее.

В любом случае, вы поняли идею.


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

Сокет отправляет поток данных, а не сообщений.Вам не следует полагаться на то, что получаемые вами пакеты будут того же размера, что и отправленные.Пакеты могут быть сгруппированы вместе, как вы уже видели, но они также могут быть разбиты.Воспользуйтесь предложением @Chad Okere о том, как убедиться, что вы получаете блоки так же, как они были отправлены.

Однако в вашем случае вы можете просто использовать

dataOutputStream.writeUTF(ar); // sends a string as UTF-8

и

String text = dataInputStream.readUTF(); // reads a string as UTF-8
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top