Сообщений: 5,863
Тем: 105
Зарегистрирован: Sep 2010
Репутация:
13,014
Собственно пришел к тому, что код, который был у меня написан неэффективен, и как следствие тормозит все. Другое дело, что я понятия не имею, как переписать этот кусок:
[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 байту мне кажется глупым занятием, хотя возможно я не прав и это решение оптимально...вообщем буду рад комментариям.
Сообщений: 2,455
Тем: 53
Зарегистрирован: Apr 2010
Репутация:
19,728
Наркоман
У тебя должен быть буфер допустим 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.
Гадаю по капче.
Сообщений: 5,863
Тем: 105
Зарегистрирован: Sep 2010
Репутация:
13,014
Мопед не мой, я только его чиню :redlol:
https://code.google.com/p/l2script/sourc...PClient.cs
Цитата:У тебя должен быть буфер допустим 16кб, ты в него принимаешь данные. Лимит буфера (сколько мы записали в буфер) возвращается методом receive. Собираем из первых 2х байт длину пакета (если ладва). Если пакет весь в буфере, то копируем нужные данные, если пакет не полностью в буфере, то делаем новый буфер и сохраняем данные у объекта клиента.
Я пытался это сделать...получил коррапченные длинные пакеты. Вообщем сегодня попробую дубль два, благо я еще разнес логику в 3 потока (получение + декрипт), обработка (крипт + отправка обратно).
Сообщений: 102
Тем: 0
Зарегистрирован: Dec 2012
Репутация:
139
Zubastic Написал:Мопед не мой, я только его чиню :redlol:
https://code.google.com/p/l2script/sourc...PClient.cs
Я пытался это сделать...получил коррапченные длинные пакеты. Вообщем сегодня попробую дубль два, благо я еще разнес логику в 3 потока (получение + декрипт), обработка (крипт + отправка обратно).
больше на велосипед с моторчиком смахивает.....)))
Если уж делать что либо, то лучше писать с нуля самим... а переделывать или доделывать то, что было сделано другими, долгое и мутное занятие.....
Сообщений: 5,863
Тем: 105
Зарегистрирован: Sep 2010
Репутация:
13,014
10-12-2015, 03:11 PM
(Сообщение последний раз редактировалось: 10-12-2015, 03:28 PM Zubastic.)
silvermain Написал:больше на велосипед с моторчиком смахивает.....)))
Если уж делать что либо, то лучше писать с нуля самим... а переделывать или доделывать то, что было сделано другими, долгое и мутное занятие..... Ты не поверишь сколько я уже там переписал
Лично мне проще взять что-то готовое и допиливать под себя, чем начинать с нуля. Не могу я в структуру ибо у меня один спагетти код получается
Добавлено через 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]
В итоге имеем фризы и очень долгую загрузку гирана....
Сообщений: 102
Тем: 0
Зарегистрирован: Dec 2012
Репутация:
139
Спойлер
Zubastic Написал:Ты не поверишь сколько я уже там переписал
Лично мне проще взять что-то готовое и допиливать под себя, чем начинать с нуля. Не могу я в структуру ибо у меня один спагетти код получается
Добавлено через 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]
В итоге имеем фризы и очень долгую загрузку гирана....
во первых, слишком много всего.... во вторых, буфер часом не велик?=)))
вот, самый простой обмен пакетами, можно перепилить легко...
1
PHP код: <?php
#region Сокет
private Socket Client;
private MemoryStream MemoryStream = new MemoryStream();
private byte[] ReceivedBuffer = new byte[2048];
#endregion
private void OnMessageReceived()
{
if (ReadInterestEnabled)
return;
lock (MemoryStream)
{
ReadInterestEnabled = true;
MemoryStream.Position = 0;
byte[] header = new byte[2];
MemoryStream.Read(header, 0, header.Length);
short packetLen = BitConverter.ToInt16(header, 0);
packetLen -= 2;
if (packetLen >= 0)
{
byte[] packet = new byte[packetLen];
MemoryStream.Read(packet, 0, packet.Length);
Crypt.Decrypt(packet);
Type pck = PacketHandler.ProcessPacket(packet, this);
if (pck != null)
{
ReceivePacket rp = (ReceivePacket)Activator.CreateInstance(pck, this, packet);
Thread pckRun = new Thread(rp.Run);
pckRun.Start();
}
else
{
}
if (MemoryStream.Position > 0)
{
byte[] data = new byte[MemoryStream.Position - MemoryStream.Position];
MemoryStream.Read(data, 0, data.Length);
MemoryStream.SetLength(0);
MemoryStream.Write(data, 0, data.Length);
OnMessageReceived();
}
else
MemoryStream.SetLength(0);
}
else
{
MemoryStream.Position = 0;
}
ReadInterestEnabled = false;
}
}
public void SendPacket(SendPacket Packet)
{
if (Packet == null)
return;
Packet.Write();
var Data = Packet.ToByteArray();
Crypt.Encrypt(Data);
List<byte> List = new List<byte>();
List.AddRange(BitConverter.GetBytes((short)(Data.Length + 2)));
List.AddRange(Data);
Client.BeginSend(List.ToArray(), 0, List.Count, SocketFlags.None, new AsyncCallback(EndWrite), Packet);
}
5 минут на коленке....
Сообщений: 5,863
Тем: 105
Зарегистрирован: Sep 2010
Репутация:
13,014
Остановился на этом:
[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]
Сообщений: 1
Тем: 0
Зарегистрирован: Mar 2016
Репутация:
0
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
|