Чтение из сокета - Форум администраторов игровых серверов
Форум администраторов игровых серверов StormWall - Защита от DDos атак
Регистрация Мнения Справка Пользователи Календарь Все разделы прочитаны
Вернуться   Форум администраторов игровых серверов > Полезное / Common > Программирование / Programming

Программирование / Programming
Ищете помощи в написании программы, есть сложность в выполнении задания (в институте и т.д.), пожалуйста, спросите у нас в данном форуме и мы обязательно вам поможем.

Ответ
Опции темы
Непрочитано 12.10.2015, 03:05   #1
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Чтение из сокета

Собственно пришел к тому, что код, который был у меня написан неэффективен, и как следствие тормозит все. Другое дело, что я понятия не имею, как переписать этот кусок:
            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();
                }
            }
Code: C++
Собирать пакет по 1 байту мне кажется глупым занятием, хотя возможно я не прав и это решение оптимально...вообщем буду рад комментариям.
__________________
Zubastic вне форума Ответить с цитированием
Непрочитано 12.10.2015, 04:23   #2
Аватар для n3k0nation
Antihero

По умолчанию Re: Чтение из сокета

Наркоман
У тебя должен быть буфер допустим 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.
Гадаю по капче.
n3k0nation вне форума Ответить с цитированием
Непрочитано 12.10.2015, 12:54   #3
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Re: Чтение из сокета

Мопед не мой, я только его чиню
https://code.google.com/p/l2script/s...g/TCPClient.cs
Цитата:
У тебя должен быть буфер допустим 16кб, ты в него принимаешь данные. Лимит буфера (сколько мы записали в буфер) возвращается методом receive. Собираем из первых 2х байт длину пакета (если ладва). Если пакет весь в буфере, то копируем нужные данные, если пакет не полностью в буфере, то делаем новый буфер и сохраняем данные у объекта клиента.
Я пытался это сделать...получил коррапченные длинные пакеты. Вообщем сегодня попробую дубль два, благо я еще разнес логику в 3 потока (получение + декрипт), обработка (крипт + отправка обратно).
__________________
Zubastic вне форума Ответить с цитированием
Непрочитано 12.10.2015, 14:54   #4
Аватар для silvermain
Участник

По умолчанию Re: Чтение из сокета

Цитата:
Сообщение от Zubastic Посмотреть сообщение
Мопед не мой, я только его чиню
https://code.google.com/p/l2script/s...g/TCPClient.cs

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

Если уж делать что либо, то лучше писать с нуля самим... а переделывать или доделывать то, что было сделано другими, долгое и мутное занятие.....
silvermain вне форума Отправить сообщение для silvermain с помощью Skype™ Ответить с цитированием
Непрочитано 12.10.2015, 15:11   #5
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Re: Чтение из сокета

Цитата:
Сообщение от silvermain Посмотреть сообщение
больше на велосипед с моторчиком смахивает.....)))

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

Добавлено через 17 минут
Переписал вот так:
                    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;
Code: C++
В итоге имеем фризы и очень долгую загрузку гирана....
__________________

Последний раз редактировалось Zubastic; 12.10.2015 в 15:28. Причина: Добавлено сообщение
Zubastic вне форума Ответить с цитированием
Непрочитано 12.10.2015, 16:20   #6
Аватар для silvermain
Участник

По умолчанию Re: Чтение из сокета

Спойлер:
Свернуть ↑Развернуть ↓


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

вот, самый простой обмен пакетами, можно перепилить легко...
1:
Свернуть ↑Развернуть ↓


5 минут на коленке....
silvermain вне форума Отправить сообщение для silvermain с помощью Skype™ Ответить с цитированием
Сказали спасибо:
Непрочитано 12.10.2015, 16:48   #7
Аватар для Zubastic
ZG troll squad

Автор темы (Топик Стартер) Re: Чтение из сокета

Остановился на этом:
        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();
                }
            }
        }
Code: C++
__________________
Zubastic вне форума Ответить с цитированием
Непрочитано 04.03.2016, 08:19   #8
Пользователь

По умолчанию Re: Чтение из сокета

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
__________________
http://www.moontextile.com/
William008 вне форума Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[Куплю] [php] чтение текста с изображения Mooni Рынок / Marketplace 8 14.03.2014 03:59
Чтение файла UTF8 [STIGMATED] Java 4 23.11.2012 22:04
Что нужно знать... Остин Программирование / Programming 7 06.12.2010 01:22


© 2007–2024 «Форум администраторов игровых серверов»
Защита сайта от DDoS атак — StormWall
Работает на Булке неизвестной версии с переводом от zCarot
Текущее время: 13:15. Часовой пояс GMT +3.

Вверх