Рейтинг темы:
  • 0 Голос(ов) - 0 в среднем
  • 1
  • 2
  • 3
  • 4
  • 5
Чтение из сокета
#1
Собственно пришел к тому, что код, который был у меня написан неэффективен, и как следствие тормозит все. Другое дело, что я понятия не имею, как переписать этот кусок:
[SRC="c++"] while (Connected)
{
try
{
var tmpbuffer = new byte[1];
SocketToServer.Receive(tmpbuffer, 1, SocketFlags.None);
var newBuffer = new byte[_bufferFc.Length + 1];
_bufferFc.CopyTo(newBuffer, 0);
newBuffer[_bufferFc.Length] = tmpbuffer[0];
var packetLength = -1;
if (newBuffer.Length > 1) packetLength = BitConverter.ToInt16(new[] { newBuffer[0], newBuffer[1] }, 0);
if (newBuffer.Length >= packetLength && packetLength != -1)
{
var finalPacket = new byte[packetLength];
var leftOver = new byte[newBuffer.Length - packetLength];
newBuffer.CopyTo(finalPacket, 0);
newBuffer.CopyTo(finalPacket, newBuffer.Length - packetLength);
newBuffer = leftOver;
DataReceivedToClient(finalPacket);
_dbg.Information(finalPacket.Length + " Fc: " + BitConverter.ToString(finalPacket));
}
_bufferFc = newBuffer;
}
catch
{
Close();
}
}[/SRC]

Собирать пакет по 1 байту мне кажется глупым занятием, хотя возможно я не прав и это решение оптимально...вообщем буду рад комментариям.
[Изображение: 4e38c909fcd08c5fcdf363b54a62.png]
Ответ
#2
Наркоман Big Grin
У тебя должен быть буфер допустим 16кб, ты в него принимаешь данные. Лимит буфера (сколько мы записали в буфер) возвращается методом receive. Собираем из первых 2х байт длину пакета (если ладва). Если пакет весь в буфере, то копируем нужные данные, если пакет не полностью в буфере, то делаем новый буфер и сохраняем данные у объекта клиента.

Пример на джаве:
Код:
                SocketChannel channel = client.getChannel();
                if(!channel.isOpen()) {
                    continue;
                }
                
                ByteBuffer buffer = client.getReadBuffer();
                if(buffer == null) {
                    buffer = directBuffer;
                } else if(!buffer.hasRemaining()) {
                    NetHelper.closeClient(client);
                    client.setReadBuffer(null);
                    bufferCache.put(buffer);
                    continue;
                }
                
                try {
                    channel.read(buffer);
                } catch (IOException e) {
                    NetHelper.closeClient(client);
                    continue;
                }
                
                buffer.flip();
                getListener().onReadClient(client, buffer);
                
                if(buffer.hasRemaining()) {
                    buffer.compact();
                    if(buffer.isDirect()) {
                        buffer = bufferCache.get();
                        buffer.put(directBuffer);
                        client.setReadBuffer(buffer);
                        directBuffer.clear();
                    }
                } else if(!buffer.isDirect()) {
                    client.setReadBuffer(null);
                    bufferCache.put(buffer);
                } else {
                    directBuffer.clear();
                }

Код:
        int pos = 0;
        for(;;) {
            if(!buffer.hasRemaining()) {
                return;
            }
            
            int pSize = header.readSize(buffer, pos);
            if(pSize > buffer.capacity() || pSize < header.getBytes() + header.getOpcodeBytes()) {
                NetHelper.closeClient(client);
                return;
            }
            
            if(pSize > buffer.remaining()) {
                return;
            }
            
            byte[] wrap = new byte[pSize];
            buffer.position(pos);
            buffer.get(wrap);
            pos += pSize;
            buffer.position(pos);
            
            ByteBuffer packetBuffer = Buffers.allocHeap(wrap);
            if(nextProcessor != null) {
                nextProcessor.onReadClient(processor, client, packetBuffer);
            }
        }
m0nster.art - clear client patches, linkz to utils & code.
Гадаю по капче.
Ответ
#3
Мопед не мой, я только его чиню :redlol:
https://code.google.com/p/l2script/sourc...PClient.cs
Цитата:У тебя должен быть буфер допустим 16кб, ты в него принимаешь данные. Лимит буфера (сколько мы записали в буфер) возвращается методом receive. Собираем из первых 2х байт длину пакета (если ладва). Если пакет весь в буфере, то копируем нужные данные, если пакет не полностью в буфере, то делаем новый буфер и сохраняем данные у объекта клиента.
Я пытался это сделать...получил коррапченные длинные пакеты. Вообщем сегодня попробую дубль два, благо я еще разнес логику в 3 потока (получение + декрипт), обработка (крипт + отправка обратно).
[Изображение: 4e38c909fcd08c5fcdf363b54a62.png]
Ответ
#4
Zubastic Написал:Мопед не мой, я только его чиню :redlol:
https://code.google.com/p/l2script/sourc...PClient.cs

Я пытался это сделать...получил коррапченные длинные пакеты. Вообщем сегодня попробую дубль два, благо я еще разнес логику в 3 потока (получение + декрипт), обработка (крипт + отправка обратно).

больше на велосипед с моторчиком смахивает.....)))

Если уж делать что либо, то лучше писать с нуля самим... а переделывать или доделывать то, что было сделано другими, долгое и мутное занятие.....
Ответ
#5
silvermain Написал:больше на велосипед с моторчиком смахивает.....)))

Если уж делать что либо, то лучше писать с нуля самим... а переделывать или доделывать то, что было сделано другими, долгое и мутное занятие.....
Ты не поверишь сколько я уже там переписал Big Grin
Лично мне проще взять что-то готовое и допиливать под себя, чем начинать с нуля. Не могу я в структуру ибо у меня один спагетти код получается Sad

Добавлено через 17 минут
Переписал вот так:
[SRC="c++"] var tmpbuffer = new byte[65536];
var len = SocketToClient.Client.Receive(tmpbuffer, SocketFlags.None);
var newBuffer = new byte[_bufferToClient.Length + len];
Array.Copy(_bufferToClient, newBuffer, _bufferToClient.Length);
Array.Copy(tmpbuffer, 0, newBuffer, _bufferToClient.Length, len);
if (newBuffer.Length > 1)
{
var packetLength = BitConverter.ToInt16(new[] { newBuffer[0], newBuffer[1] }, 0);
if (newBuffer.Length >= packetLength)
{
var inputPacket = new byte[packetLength];
var leftOver = new byte[newBuffer.Length - packetLength];
Array.Copy(newBuffer, inputPacket, packetLength);
Array.Copy(newBuffer, packetLength, leftOver, 0, newBuffer.Length - packetLength);
newBuffer = leftOver;
_readFromClient.Add(inputPacket);
//_dbg.Information("[ReadFromServer] Raw Packet:" + BitConverter.ToString(inputPacket));
//new Thread(() => DataReceivedFc(ref finalPacket)).Start();
}
}
_bufferToClient = newBuffer;[/SRC]
В итоге имеем фризы и очень долгую загрузку гирана....
[Изображение: 4e38c909fcd08c5fcdf363b54a62.png]
Ответ
#6
Спойлер

во первых, слишком много всего.... во вторых, буфер часом не велик?=)))

вот, самый простой обмен пакетами, можно перепилить легко...
1

5 минут на коленке....
Ответ
#7
Остановился на этом:
[SRC="c++"] private void TcpListenToClient()
{
var offset = 0;
var buffer = new byte[16384];
Connected = SocketToClient.Connected;
while (Connected)
{
try
{
offset += SocketToClient.GetStream().Read(buffer, offset, 16384 - offset);
var packetLength = BitConverter.ToInt16(new[] {buffer[0], buffer[1]}, 0);
while (offset >= packetLength && packetLength > 0)
{
var inputPacket = new byte[packetLength];
offset -= packetLength;
Array.Copy(buffer, 0, inputPacket, 0, packetLength);
Array.Copy(buffer, packetLength, buffer, 0, 16384 - packetLength);
_readFromClient.Add(inputPacket);
_dbg.Information("[ReadFromClient] Raw Packet:" + BitConverter.ToString(inputPacket));
packetLength = BitConverter.ToInt16(new[] {buffer[0], buffer[1]}, 0);
}
}
catch
{
Close();
}
}
}[/SRC]
[Изображение: 4e38c909fcd08c5fcdf363b54a62.png]
Ответ
#8
more on a bike with an engine looks like ) If we accomplish something, it is best to compose sans preparation yourself ... what's more, to redesign or complete what has been finished by others, long and dull lesson
Ответ


Возможно похожие темы ...
Тема Автор Ответы Просмотры Последний пост
  Чтение массива и вычитание Milirina 0 1,231 07-24-2022, 03:21 PM
Последний пост: Milirina
  Чтение памяти процесса Shayne 2 2,412 05-17-2017, 09:35 PM
Последний пост: VOLKyiv

Перейти к форуму:


Пользователи, просматривающие эту тему: 3 Гость(ей)