"Потеря" пакетов сервер-клиент

Рейтинг: 1Ответов: 0Опубликовано: 31.03.2015

Здравствуйте. У меня есть проблема, которая я не знаю с чем связана.

Имеется сервер на Java (Netty) и клиент на Unity. Обмен сообщениями происходит используя ProtoBuf.

И вприниципе было все хорошо, только иногда "терялись" пакеты. Собственно в этом и заключается проблема.

Я честно говоря не очень сильно силен в tcp соединении, но как я понимаю этот протокол гарантирует доставку пакета.

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

Очень прошу помочь в том чтобы понять хотябы ГДЕ проблема. Отправляю с сервака сообщения я вот так:

private synchronized void groupBroadCast(Object message){
        for (Channel userChannel : channels) {
            userChannel.write( message );
        }
    }

но когда возникла данная проблема после многих попыток и по моему даже глупых была найдена возможность сильно понизить пропажу пакетов. Смысл в том что я просто после write делаю wait. Вот так:

private synchronized void groupBroadCast(Object message){
    for (Channel userChannel : channels) {
        try {
            synchronized (userChannel) {
                userChannel.wait(1);
                userChannel.write( message );
            }
        } catch (Exception e) {
            System.out.println("broadCast.groupBroadCast error :" + e);
        }
    }
}

В итоге из 20 пакетов гдето в 9/10 случаев нету вообще потерь. Раньше было что доходили все только в 1/10. Кстати проблема бывает еще по-моему и в том что приходит часть пакета(У протобафа возникают проблемы с десерреализацией)

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

Безусловно я не отрицаю и возможную проблему в самом принятии сообщений, и к сожалению нормального тцп клиента я не нашел. Нашел только SIMPLE примеры... из которых сделал свой.

Вот код клиента :

private void ReceiveCallback( IAsyncResult ar ) {
    try {
        StateObject state = (StateObject) ar.AsyncState;
        responseLength = client.EndReceive(ar);

        if (responseLength > 0) {
            response = state.buffer;
            lock (response){
            deserMessage();
            }
            readyToRead = true;
        }
        client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
    } catch (Exception e) {
        Debug.Log("tcpAsync.RecieveCallback error : "+e.ToString());
    }
}
public void deserMessage(){
    byte[] bytes = new byte[responseLength];
    for (int i =0; i< responseLength;i++){
        bytes[i]= response[i];
    }
    Stream stream = new MemoryStream(bytes);

    respObject.Add ( Serializer.Deserialize<respPacket>(stream) );
}

Я честно говоря очень слаб в этом и до конца не понимаю как должна выглядеть обработка когда приходит сразу много сообщений. Очень прошу подсказать хотя бы ГДЕ проблема.. Хотя бы на серваке или клиенте.

Ответы

Ответов пока нет.