Показать сообщение отдельно
Старый 05.02.2012, 22:30   #1
Местный
 
Регистрация: 23.02.2009
Сообщений: 319
Сказал Спасибо: 72
Имеет 60 спасибок в 45 сообщенях
Kilatif пока неопределено
По умолчанию C#, сокеты, l2phx

Пишу программку на C#, что то типа ООГ бота. Подобные программы я уже писал на Delphi и Qt, теперь решил попробовать на C#. Все отлично, но везде свой подход работы с сокетами. И я столкнулся с какой-то достаточно интересной проблемой...

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

Подключаюсь я к GS и сразу отправляю ProtocolVersion размером 267 байт (ему впринципе и 7 хватает, но клиент посылает еще какую-то дрянь вконце и поэтому посылаю ее и я).
После этого клиент мне присылает KeyInit.
Я инициализирую свой Xor и отправляю ему RequestAuthLogin иии... и все. В ответ тишина.

В логах анализатора трафика (Wireshark) этот пакет на сервер видно что отправляется.
Сразу возникает логичная догадка о том, что я неправильно сформировал пакет, но не тут то было.
Когда я посылаю ProtocolVersion размером < 256 байт, то тогда сервер мне вполне нормально присылает ответ на RequestAuthLogin.

Для дебага этой проблемы я решил подключить l2phx.
Подключил его с помощью LSP перехвата соединения и начал следить.

Когда посылаю ProtocolVersion 267 байт, то происходит полная херня:
в программе четко и ясно отсылаю 267 байт, а отсылается только 11, что четко видно как в логах l2phx, так и в логах Wireshark.
Следующие за таким пакетом от клиента вообще больше не отсылаются, сколько бы я не пытался, при этом соединение не разрывается, именно я пытаюсь отослать пакет, а он не отправляется на сервер. К тому же, методом тыка получил простую закономерность, что отсылается как раз таки N mod 256 байт.
Если отсылается < 256 байт пакет, то и с l2phx все работает нормально.

Происходит это конкретно в C# и нигде больше, поэтому посчитал какой-то особенностью работы с сокетами о которых я не знаю.
Чтение пакетов я осуществляю в новом потоке в цикле:
Код:
        private void PacketsReader()
        {
            while (isClientConnected)
            {
                byte[] size = new byte[4];

                lock (thisLock)
                {
                    client.Receive(size, 2, SocketFlags.None);
                }
                packetSize = BitConverter.ToInt32(size, 0);
                packetSize -= 2;

                if (packetSize > 0)
                {
                    packet = new byte[packetSize];
                    client.Receive(packet, packetSize, SocketFlags.None);

                    packet = crypter.Decrypt(packet, packetSize);
                    parser.Parse(packet, packetSize);
                }
            }
        }
Как видно из кода, после дешифрации пакет отправляется на парсер, где определяется тип пакета и вызывается соответствующая ф-я для обработки.
Отправка пакета происходит вот так:
Код:
        public void SendPacket(byte[] packet, int packetSize, bool isEncrypt = true)
        {
            byte[] temp = new byte[packetSize];

            Array.Copy(packet, 0, temp, 0, packetSize);
            if (isEncrypt) temp = crypter.Encrypt(temp, packetSize);

            byte[] sendPacket;

            packetSize += 2;
            sendPacket = new byte[packetSize];

            Array.Copy(BitConverter.GetBytes((byte)packetSize), 0, sendPacket, 0, 2);
            Array.Copy(temp, 0, sendPacket, 2, packetSize - 2);

            lock (thisLock)
            {
                client.Send(sendPacket);
            }
        }
Кто знает почему происходит такая ерунда?
P.S. Если что-то тут не указал, спрашивайте - укажу, отвечу.
Kilatif вне форума   Ответить с цитированием