Пишу программку на 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. Если что-то тут не указал, спрашивайте - укажу, отвечу.