Задание corb: обработка исключения serverconnectionexception: сброс соединения одноранговым узлом

Одноранговые топологии

Типичные способы использования одноранговой репликации проиллюстрированы следующими сценариями.

Топология с двумя участвующими базами данных

На обоих приведенных выше рисунках показаны две участвующие базы данных и пользовательский трафик, направленный к базам данных через сервер приложений. Такую конфигурацию можно использовать для различных приложений — от веб-сайтов до приложений рабочих групп. Это позволяет получить следующие преимущества.

  • Улучшенная производительность операции чтения, так как чтение распределено на два сервера.

  • Более высокая доступность при необходимости обслуживания или в случае сбоя одного из узлов.

На обеих иллюстрациях операция чтения между участвующими базами данных сбалансирована, но обновления обрабатываются разными способами:

  • Слева операции обновления секционируются между двумя серверами. Если база данных содержит каталог продукции, можно, например, создать пользовательское приложение, направляющее обновления продуктов, начинающихся символами с «А» до «М», на узел A , а обновления продуктов с «Н» до «Я» — на узел B .

  • Справа все обновления направляются на узел В. С узла В обновления реплицируются на узел A. Если узел B находится в режиме «вне сети» (например, на обслуживании), сервер приложений может направлять все операции на узел A. Когда узел B переходит в режим «в сети», на него можно направлять обновления и сервер приложений может переместить все обновления обратно на узел B или сохранить их передачу на узел A.

Одноранговая репликация поддерживает любой из этих подходов, но основной пример обновления, показанный справа, также часто используется для стандартной репликации транзакций.

Топологии с тремя или более участвующими базами данных

На предыдущем рисунке показаны три участвующие базы данных, предоставляющие данные для глобальной организации по поддержке программного обеспечения с офисами в Лос-Анджелесе, Лондоне и Тайбэе. Инженеры службы поддержки во всех офисах принимают звонки клиентов, вводят и обновляют сведения о каждом звонке. Часовые пояса трех офисов отличаются на восемь часов, поэтому рабочие часы не перекрываются. Когда закрывается офис в Тайбэе, открывается офис в Лондоне. Если звонок находится в стадии обработки во время закрытия одного офиса, он передается представителю в другой открытый офис.

В каждом офисе имеется база данных и сервер приложений, которые используются инженерами службы поддержки для ввода и обновления сведений о звонках клиентов. Топология секционируется по времени. Поэтому обновления происходят на узле, открытом для бизнеса в текущее время, а затем передаются в другие участвующие базы данных. Данная топология обеспечивает следующие преимущества:

  • Независимость без изоляции: в каждом офисе можно независимо добавлять, обновлять или удалять данные; при этом также можно использовать данные совместно, так как они реплицируются во все участвующие базы данных.

  • Более высокая доступность в случае сбоя или во время обслуживания одной или нескольких участвующих баз данных.

    На предыдущем рисунке показано добавление узла в топологию с тремя узлами. В этом сценарии узел можно добавить по следующим причинам.

  • Так как другой офис открыт.

  • Чтобы обеспечить более высокую доступность в целях поддержки обслуживания или повышения отказоустойчивости при сбое диска или других серьезных неисправностях.

Обратите внимание, что в обеих трех- и четырехузловых топологиях все базы данных публикуют свои данные и подписываются на данные из остальных баз данных. Этим обеспечивается максимальная доступность при проведении обслуживания или в случае сбоя на одном или нескольких узлах

По мере добавления узлов необходимо соблюдать баланс между доступностью и масштабируемостью с одной стороны и производительностью, сложностью развертывания и администрирования с другой стороны.

Как устранить ошибку Java.net.ConnectException?

Способ исправления ошибки «Java.net.ConnectException» зависит от причины, по которой она появляется. Рассмотрим ситуации, с которыми пользователи сталкиваются чаще всего.

Обновление Java

Ошибка при запуске Minecraft может быть связана с тем, что версия Java на компьютере устарела. Ее можно обновить разными способами, самым простым из которых является скачивание программы с официального сайта. Откройте ссылку http://www.java.com/ru/download/ и нажмите на кнопку загрузки, а затем согласитесь с условиями лицензионного соглашения. Файл будет загружен на компьютер, после чего вам останется его запустить.

Если вам нужна более подробная информация о Java — читайте нашу статью.

Проблема на сервере

Систематически на каждом игровом сервере проходят технические работы. Если в этот момент вы попытаетесь запустить игру, выскочит ошибка «Java.net.ConnectException: Connection timed out: no further information». Зайдите на официальный форум и найдите информацию о технических работах, а также попробуйте подключиться позднее.

Антивирус и брандмауэр

Нельзя исключать блокировку игры антивирусной программой или брандмауэром. Попробуйте временно отключить антивирус и добавить игру в список исключения в брандмауэре (также его можно на время выключить). Как отключить брандмауэр вы разберетесь, посмотрев на скриншот. Если после этого ошибка исчезнет, проблема найдена.

Версия игры

Разработчики игры Minecraft постоянно выпускают обновления. Установленная на вашем компьютере версия должна соответствовать той, под которую создан сервер. В противном случае, при подключении к нему у вас может появляться ошибка «Java.net.ConnectException: Connection timed out: no further information». Версия игры указывается на главном экране в правом нижнем углу, ее видно при запуске игры:

Игровые моды

Иногда упомянутая ошибка при подключении к серверам Майнкрафт появиться в том случае, если у вас установлено слишком много модов или расширений. Некоторые из них переполнены багами, вызывающими системные ошибки. Перед скачиванием и установкой нового мода убедитесь в том, что разработчик проверен. Попробуйте удалить последние установленные моды, после которых начала появляться ошибка с Java.

Платная подписка

Многие сервера для игры в Minecraft платные, то есть геймерам требуется специальная подписка. Когда ее срок действия истекает, вы больше не сможете подключиться к серверу. При этом вместо понятного предупреждения появляется все та же ошибка с сообщением «Java.net.ConnectException Connection timed out: no further information».

Как решить проблему с SocketException

SocketException – это общее исключение, обозначающее проблему при попытке доступа или открытия Socket. Решение этой проблемы должно быть сделано с особой тщательностью. Вы должны всегда регистрировать сообщение об ошибке, которое сопровождает исключение.

В предыдущем примере мы видели код сообщения. Это происходит, когда один из участников принудительно закрывает соединение без использования close(). Это означает, что вы должны проверить, был ли один из участников неожиданно прерван.

Также может быть сообщение «Слишком много открытых файлов», особенно если вы работаете в Linux. Это сообщение обозначает, что многие файловые дескрипторы открыты для системы. Вы можете избежать этой ошибки, если перейдете в /etc/sysctl.conf и увеличите число в поле fs.file-max. Или попытаться выделить больше стековой памяти.

Конечно, можно встретить много других сообщений. Например, «Ошибка привязки», где ваше соединение не может быть установлено, поскольку порт не может быть привязан к сокету. В этом случае проверьте, используется ли порт и т. д.

Если у вас проблема с minecraft, то чтобы решить проблему попробуйте сделать следующее:

Оцени статью

Оценить

Средняя оценка / 5. Количество голосов:

Видим, что вы не нашли ответ на свой вопрос.

Помогите улучшить статью.

Спасибо за ваши отзыв!

[android] MonkeyRunner Решение проблемы с java.net.SocketException: сломанная труба

http-equiv=»Content-Type» content=»text/html;charset=UTF-8″>yle=»margin-bottom:5px;»>Теги:  monkeyrunner

Оказалось, что после начала активности я всегда сообщал java.net.SocketException: исключение из-за разбитого канала после сна. Убедитесь, что у сценария нет проблем, и я не смог найти решение проблемы в сети, но я могу найти проблему с mysql. В чем причина, когда проблема возникает в mysql, используемое позже соединение теряется спереди, поэтому возникает эта проблема. Точно так же, после запуска активности на monkeyrunner, сон легко лишает законной силы соединение adb, и сценарий вступает в силу после комментирования сна.

Интеллектуальная рекомендация

1. Для реальных сигналов (для понимания): A (ω) является соотношением амплитуды выходного сигнала и амплитуды входного сигнала, называемого частотой амплитуды. Φ (ω) — это разница межд…

Один. вести Многие люди задавали некоторые вопросы о создании проекта Flex + LCDS (FDS) в сообщениях и группах. Из-за операции ее трудно четко объяснить, поэтому я написал простой учебник (я обещал эт…

package com.example.phonehttp; import android.os.Bundle; import android.os.Handler; import android.app.Activity; import android.widget.ScrollView; import android.widget.TextView; public class MainActi…

Он предназначен для реализации подкласса того же родительского класса с родительским классом. Полиморфизм Один и тот же ссылочный тип использует разные экземпляры для выполнения разных операций; Идея …

тема: Объедините два упорядоченных слоя в новый заказанный список и возврат. Новый список состоит из всех узлов двух связанных списков, данных сплавным. Пример: Анализ: два связанных списка состоит в …

Вам также может понравиться

D. Самая ценная строка Пример ввода 2 2 aa aaa 2 b c Образец вывода aaa c На самом деле, будучи задетым этим вопросом, вы должны быть осторожны. После инвертирования строки, если две строки имеют один…

Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surro…

calc () может быть очень незнакомым для всех, и трудно поверить, что calc () является частью CSS. Поскольку он выглядит как функция, почему он появляется в CSS, поскольку это функция? Этот момент такж…

Основываясь на дереве регрессии, сформированном CART, а также на предварительной и последующей обрезке дерева, код выглядит следующим образом:…

Откат Обновление в режиме онлайн с версии Centos (CentOS Linux версии 7.3.1611 (Core) до CentOS Linux версии 7.5.1804 (Core)) # ошибка соединения yum-ssh после обновления yexpected key exchange group …

Возможное использование

  • Совместное зеркалирование: механизм балансировки нагрузки с помощью локальной сети, в которой размещается информация, доступная для компьютеров за пределами локальной сети. Эта схема может позволить разработчикам распределять нагрузку между множеством компьютеров вместо центрального сервера, чтобы гарантировать доступность своего продукта.
  • Хранилище с разделением по времени: в сети, когда компьютер подключается к сети, его доступные данные распределяются по сети для извлечения, когда этот компьютер отключается от сети. Так же, как данные других компьютеров, отправляются на рассматриваемый компьютер для автономного извлечения, когда они больше не подключены к сети. В основном для узлов без возможности постоянного подключения к сети.
  • Распределенные индексы: поиск файлов по сети в базе данных с возможностью поиска. например, клиенты передачи файлов P2P.
  • Крупномасштабный комбинаторный поиск: ключи, являющиеся вариантами решения проблемы, и каждое отображение ключа на узел или компьютер, который отвечает за их оценку как решение или нет. например, взлом кода
  • Также используется в беспроводных сенсорных сетях для обеспечения надежности

Разрешение имени однорангового узла

Поиск других одноранговых узлов в сети PNRP или облаке состоит из двух этапов:

  1. Определение конечной точки

  2. Разрешение идентификатора PNRP

На этапе определения конечной точки одноранговый узел, который пытается разрешить идентификатор PNRP службы на другом компьютере, определяет IPv6-адрес этого удаленного однорангового узла. В качестве удаленного однорангового узла выступает узел, который опубликован или связан с идентификатором PNRP компьютера или службы.

После подтверждения регистрации удаленной конечной точки в облаке PNRP запрашивающий одноранговый узел на этапе разрешения идентификатора PNRP отправляет запрос к этой конечной точке однорангового узла для получения идентификатора PNRP требуемой службы. Конечная точка отправляет ответ с подтверждением идентификатора PNRP службы, комментарий, а также до 4 КБ дополнительной информации, которую запрашивающий одноранговый узел может использовать для обмена данными в дальнейшем. Например, если требуемая конечная точка является игровым сервером, в дополнительных данных записи с именем однорангового узла могут содержаться сведения об игре, достигнутом уровне, а также текущем количестве игроков.

На этапе определения конечной точки PNRP использует итеративный процесс для поиска узла, который опубликовал идентификатор PNRP. В этом случае выполняющий разрешение узел отвечает за обращение к узлам, которые максимально близки к целевому идентификатору PNRP.

Чтобы выполнить разрешение имен в PNRP, одноранговый узел анализирует записи в собственном кэше на наличие записи, которая соответствует целевому идентификатору PNRP. Если такая запись найдена, одноранговый узел отправляет сообщение запроса PNRP к одноранговому узлу и ожидает ответа. Если запись для идентификатора PNRP не найдена, одноранговый узел отправляет сообщение запроса PNRP к одноранговому узлу, который соответствует записи с идентификатором PNRP, наиболее полно соответствующим целевому идентификатору PNRP. Узел, получающий сообщение запроса PNRP, анализирует собственный кэш и выполняет следующие действия:

  • Если идентификатор PNRP найден, запрошенный одноранговый узел конечной точки отвечает непосредственно запрашивающему одноранговому узлу.

  • Если идентификатор PNRP не найден, а идентификатор PNRP близок к целевому, запрошенный одноранговый узел отправляет запрашивающему узлу ответ, содержащий IPv6-адрес однорангового узла, который представляет запись с идентификатором PNRP, наиболее близко соответствующим целевому идентификатору PNRP. Используя IP-адрес в ответе, запрашивающий узел отправляет другое сообщение запроса PNRP по этому IPv6-адресу, чтобы дать ответ или проанализировать свой кэш.

  • Если идентификатор PNRP не найден и близкий к конечному идентификатор PNRP отсутствует в кэше, запрошенный одноранговый узел отправляет запрашивающему узлу ответ, указывающий на это состояние. После этого запрашивающий одноранговый узел выбирает идентификатор PNRP следующего ближайшего узла.

Запрашивающий узел продолжает этот процесс, повторяя итерации, пока не будет найден узел, зарегистрировавший идентификатор PNRP.

В пространстве имен System.Net.PeerToPeer определено отношение «многие ко многим» между записями PeerName, содержащими конечные точки, и одноранговыми сетями или облаками PNRP, в которых они осуществляют обмен данными. При наличии повторяющихся или устаревших записей или нескольких узлов с одинаковыми именами однорангового узла узлы PNRP могут получать актуальную информацию с помощью класса PeerNameResolver. Методы PeerNameResolver используют одно имя однорангового узла, упрощая соотношение между именами одноранговых узлов и записями или облаками до «один ко многим». Это поведение аналогично выполнению запроса с использованием соединения реляционной таблицы. В случае успешного выполнения объект Resolver возвращает PeerNameRecordCollection для заданного имени однорангового узла. Например, имя однорангового узла может встречаться во всех записях имен одноранговых узлов в коллекции с упорядочением по облаку. Для этих экземпляров имен одноранговых узлов приложение на основе протокола PNRP сможет запрашивать вспомогательные данные.

Почему именно «одноранговые»?

Если рассматривать ситуацию с точки зрения информационных технологий, то одноранговые или пиринговые (от peer-to-peer) сети – это такие сети, в которых отельные элементы (узлы) обмениваются между собой файлами и хранят один и тот же набор данных. Узлы равны по мощности и выполняют одинаковые по смыслу задачи.

В любом случае, о первых эффективных одноранговых сетях начали говорить примерно в девяностых годах прошлого века, когда появились программы для эффективного обмена файлами. Однако основной интерес к ним вспыхнул после появления криптовалютных сетей, основанных на классической P2P-архитектуре. Впрочем, теперь такие сети используются не только в криптоэкономике, но и при создании поисковых систем, стриминг-платформ, разнообразных онлайн-рынков и в рамках межпланетной файловой системы IPFS.

9 ответов

  • 65 рейтинг

    Это вызвано записью в соединение, когда другой конец уже закрыл его.

    Итак, у вас плохо определен или реализован протокол приложения.

    ответ дан user207421, с репутацией 255862, 22.02.2010

  • 23 рейтинг

    В нашем случае мы столкнулись с этим при выполнении нагрузочного теста на нашем сервере приложений. Выяснилось, что нам нужно добавить дополнительную память в нашу JVM, потому что она заканчивалась. Это решило проблему.

    Попробуйте увеличить объем памяти, доступной для JVM, и / или отслеживать использование памяти при появлении этих ошибок.

    ответ дан Dave, с репутацией 247, 15.08.2012

  • 4 рейтинг

    Все открытые потоки & amp; соединения должны быть правильно закрыты, поэтому в следующий раз, когда мы попытаемся использовать объект urlConnection, он не выдаст ошибку. Как пример, следующее изменение кода исправило ошибку для меня.

    До:

    После:

    ответ дан Murali Mohan, с репутацией 65, 14.09.2012

  • 3 рейтинг

    SocketException: Сломанный канал, вызван тем, что «другой конец» (клиент или сервер) закрывает соединение, в то время как ваш код читает или пишет в соединение.

    Это очень распространенное исключение в клиент-серверных приложениях, которые получают трафик от клиентов или серверов вне контроля приложения. Например, клиент является браузером. Если браузер выполняет Ajax-вызов и / или пользователь просто закрывает страницу или браузер, то это может неожиданно прекратить все коммуникации. По сути, вы увидите эту ошибку каждый раз, когда другой конец завершает свое приложение, и вы не ожидали этого.

    Если вы столкнулись с этим исключением в вашем приложении, то это означает, что вы должны проверить свой код, где происходит IO (ввод / вывод), и обернуть его блоком try / catch, чтобы перехватить это IOException. Тогда вы сами решаете, как вы хотите справиться с этой полуактивной ситуацией.

    В вашем случае, самое раннее место, где у вас все еще есть контроль, — это вызов . Поэтому убедитесь, что вызов обернут блоком try / catch, и обрабатывайте его так, как считаете нужным.

    Я бы настоятельно рекомендовал не регистрировать ошибки, связанные с SocketException-Broken Pipe, на любых уровнях, кроме уровней отладки / трассировки. Иначе, это может использоваться как форма атаки DOS (отказа в обслуживании), заполняя журналы. Попробуйте и подвергните негативному тестированию свое приложение для этого распространенного сценария.

    ответ дан AndyGee, с репутацией 41, 12.02.2018

  • 1 рейтинг

    Я реализовал функцию загрузки данных через FTP-сервер и нашел там то же исключение при возобновлении загрузки. Чтобы устранить это исключение, вам всегда нужно будет отключиться от предыдущего сеанса и создать новый экземпляр клиента и новое соединение с сервером. Этот же подход может быть полезен и для HTTPClient.

    ответ дан Naeem Ahmad, с репутацией 27, 18.08.2011

  • 1 рейтинг

    Причина в том, что удаленный узел закрывает свой сокет (например, сбой), поэтому, если вы попытаетесь записать в него данные, например, вы получите это. чтобы решить эту проблему, вставьте операции чтения / записи в сокет между:

    ответ дан elhadi dp ıpɐɥןǝ, с репутацией 2713, 11.08.2017

  • 0 рейтинг

    Приведенные выше ответы иллюстрируют причину этого : другой конец закрыл соединение. Я хотел бы поделиться опытом, что случилось, когда я столкнулся с этим:

    1. в запросе клиента заголовок по ошибке установлен больше, чем тело запроса на самом деле (фактически тела вообще не было)
    2. нижний сервис в сокете tomcat ожидал данные тела такого размера (http — это TCP, который обеспечивает доставку с помощью инкапсуляции и. , , )
    3. по истечении 60 секунд tomcat выдает исключение тайм-аута:
    4. клиент получает ответ с кодом состояния 500 из-за исключения тайм-аута.
    5. Клиент закрывает соединение (потому что получает ответ).
    6. Кот бросает , потому что клиент закрыл его.

    Иногда tomcat не генерирует исключение нарушенного пипса, потому что исключение тайм-аута закрывает соединение, поэтому такая разница меня смущает.

    ответ дан Tiina, с репутацией 1095, 2.02.2018

  • -1 рейтинг

    Возможно, проблема в том, что ваши развернутые файлы не обновляются с правильными методами RMI. Убедитесь, что ваш интерфейс RMI имеет обновленные параметры или обновленные структуры данных, которых нет у вашего клиента. Или что ваш RMI-клиент не имеет параметров, которые отличаются от версии вашего сервера.

    Это просто обоснованное предположение. После повторного развертывания файлов классов моего серверного приложения и повторного тестирования проблема «Сломанной трубы» ушла.

    ответ дан JonAar, с репутацией 99, 5.06.2017

  • -1 рейтинг

    Вы должны увеличить параметр «backlog» вашего ServerSocket, например,

    ответ дан TheSecond, с репутацией 148, 13.11.2015

Детали протокола

Сеть Chord с 16 узлами. Выделены «пальцы» одного из узлов.

Базовый запрос

Основное использование протокола Chord — запрос ключа у клиента (обычно также у узла), то есть для поиска . Базовый подход — передать запрос наследнику узла, если он не может найти ключ локально. Это приведет к запросу времени, где — количество машин в кольце.
sтыccеssор(k){\ Displaystyle преемник (k)}О(N){\ Displaystyle О (Н)}N{\ displaystyle N}

Палец стол

Чтобы избежать линейного поиска, описанного выше, Chord реализует более быстрый метод поиска, требуя, чтобы каждый узел вел таблицу finger, содержащую до записей, напомним, что это количество бит в хеш-ключе. Запись узла будет содержать . Первая запись в таблице finger фактически является непосредственным преемником узла (и поэтому дополнительное поле-преемник не требуется). Каждый раз, когда узел хочет найти ключ , он передает запрос ближайшему преемнику или предшественнику (в зависимости от таблицы finger) в своей таблице finger («самый большой» в круге, идентификатор которого меньше чем ), пока узел не узнает, что ключ хранится в его непосредственном преемнике.
м{\ displaystyle m}м{\ displaystyle m}ятчас{\ displaystyle i ^ {th}}п{\ displaystyle n}sтыccеssор((п+2я-1)мод2м){\ displaystyle наследник ((n + 2 ^ {i-1}) \, {\ bmod {\,}} 2 ^ {m})}k{\ displaystyle k}k{\ displaystyle k}k{\ displaystyle k}

С такой таблицей finger количество узлов, с которыми необходимо связаться, чтобы найти преемника в сети с N- узлами, равно . (См. Доказательство ниже.)
О(бревно⁡N){\ Displaystyle О (\ журнал N)}

Присоединение к узлу

Каждый раз, когда присоединяется новый узел, должны поддерживаться три инварианта (первые два гарантируют правильность, а последний продолжает быстро запрашивать):

  1. Преемник каждого узла правильно указывает на своего непосредственного преемника.
  2. Каждый ключ хранится в .sтыccеssор(k){\ Displaystyle преемник (k)}
  3. Таблица пальцев каждого узла должна быть правильной.

Чтобы удовлетворить эти инварианты, для каждого узла поддерживается поле- предшественник . Поскольку преемником является первая запись в таблице finger, нам больше не нужно поддерживать это поле отдельно. Для вновь присоединенного узла необходимо выполнить следующие задачи :
п{\ displaystyle n}

  1. Инициализируйте узел (предшественник и таблицу пальцев).п{\ displaystyle n}
  2. Сообщите другим узлам об обновлении их предшественников и таблиц пальцев.
  3. Новый узел берет на себя ответственные ключи от своего преемника.

Предшественник можно легко получить от предшественника (в предыдущем круге). Что касается его таблицы пальцев, существуют различные методы инициализации. Самый простой — выполнить запросы на поиск преемника для всех записей, что приведет к увеличению времени инициализации. Лучше всего проверить, является ли запись в таблице finger по-прежнему правильной для записи. Это приведет к . Лучшим методом является инициализация таблицы finger из ее ближайших соседей и внесение некоторых обновлений, которые есть .
п{\ displaystyle n}sтыccеssор(п){\ Displaystyle преемник (п)}м{\ displaystyle m}О(Mбревно⁡N){\ Displaystyle О (М \ журнал N)}ятчас{\ displaystyle i ^ {th}}(я+1)тчас{\ Displaystyle (я + 1) ^ {th}}О(бревно2⁡N){\ Displaystyle О (\ журнал ^ {2} N)}О(бревно⁡N){\ Displaystyle О (\ журнал N)}

Стабилизация

Для обеспечения правильного поиска все указатели-преемники должны быть в актуальном состоянии. Поэтому протокол стабилизации периодически выполняется в фоновом режиме, который обновляет таблицы пальцев и указатели-преемники.

Протокол стабилизации работает следующим образом:

  • Stabilize (): n запрашивает у своего преемника своего предшественника p и решает, должен ли p быть преемником n (это тот случай, если p недавно присоединился к системе).
  • Notify (): уведомляет наследника n о своем существовании, поэтому он может изменить своего предшественника на n
  • Fix_fingers (): обновляет таблицы пальцев
Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: