Java Socket - Кажется, что InputStream читает зависает - PullRequest
0 голосов
/ 23 октября 2019

Я портирую некоторый код C # на код Java, и я сделал это правильно (надеюсь), но я до сих пор не знаю, как вести себя или чего мне не хватает в порте Java.

Справочная информация: Эточтение и отправка пакетов сокетом сервера (в виде байта []). У меня нет доступа к клиентскому уровню, но структура находится прямо на стороне сервера (поэтому клиент может принять)

C # код использует NetworkStream для записи / чтения.
Java-код использует InputStream & OutputStream длязапись / чтение.

код C #: (метод потока запускается через Thread.start)

public override void ReceivingThread(object o)
{
        Client client = (Client)o;
        PacketStream clientStream = client.PacketStream;
        byte[] clientBuffer = new byte[4096];

        packetHandler.SendFirstPacket(client);

        while ((!this.Stopped) && (clientStream.Read(clientBuffer, 0, 8) != 0))
        {
            if (BitConverter.ToInt16(clientBuffer, 6) > 0)
            {
                clientStream.Read(clientBuffer, 8, BitConverter.ToInt16(clientBuffer, 6));
            }

        Packet packet = new Packet(clientBuffer);
        Console.WriteLine($"RECV [{packet.PacketId:X4}] {BitConverter.ToString(packet.GetRawPacket(), 0, packet.DataLength + 8)}");
        packetHandler.HandlePacket(client, packet);
    }
    Console.WriteLine("outside of loop");
}

Сценарий: сервер отправляет первый пакет, клиент читает его и отправляет учетные данные (в данном случае), сервер проверяет их. Чтобы упростить процесс, сейчас я отправляю пакет с кодом, указывающим, что учетные данные недействительны (код -4 как короткий -> 4002). Клиент принимает это немедленно, и поток отбрасывается. («вне цикла» ударил). Клиент не зависает и не сервер.

Я тиражировал или, точнее сказать, перенес этот код и функциональность в Java.
Поскольку в Java вы не можете запускать потоки как методы в форме расширения потокаи т.д. Я начинаю тему с помощью Java8 & lambdas. (new Thread(() -> receivingThread(client)).start();)

@Override
public void receivingThread(Object o) {

    Client client = (Client) o;
    PacketStream clientStream = client.getPacketStream();

    byte[] clientBuffer = new byte[4096];

    packetHandler.sendWelcomePacket(client);

    while ((!this.stopped) && (clientStream.read(clientBuffer, 0, 8) != -1)) {

        if (BitKit.bytesToShort(clientBuffer, 6) > -1)
            clientStream.read(clientBuffer, 8, BitKit.bytesToShort(clientBuffer, 6));

        Packet packet = new Packet(clientBuffer);
        logger.info("RECV [" + String.format("0x%x", (int)packet.getPacketId()) + "] " + BitKit.toString(packet.getRawPacket(), 0, packet.getDataLength() + 8));

        packetHandler.handlePacket(client, packet);
    }
    logger.info("outside of loop");
}

NetworkStream.Read возвращает 0, Java InputStream.read возвращает -1 для eof.
Дело в том, что в порту Java он зависает после отправки второго пакета,Вроде как-то блоки чтения каким-то ненормальным образом. Я думаю, что это около минуты или около того. Затем клиент выдает ошибку соединения вместо кода, который я отправил со второй записью.

Потоки настроены в конструкторе класса Client, который передается вниз. Операции записи и чтения предназначены для необработанных данных -> read(byte[] buffer, int offset, int size)

Есть идеи по этому поводу?
Почему он работает на C # end, а не на Java? Работает ли C # с пакетами иначе, чем Java? Любая помощь приветствуется и спасибо вперед!

PS: Извините за длинный текст:)

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