/// <summary> /// Инициализирует экземпляр ICQException. /// </summary> /// <param name="client">ICQClient, с которым связано исключение</param> /// <param name="message">Общее описание ошибки</param> /// <param name="errorCode">Код ошибки ICQ.ICQError</param> /// <param name="helpUrl">URL-ссылка для помощи в решнии проблемы (ICQ)</param> /// <param name="inner">Внутренее исключение</param> public ICQException(ICQClient client, string message, string helpUrl = null, ushort errorCode = 0, Exception inner = null) : base(message, inner) { this.Client = client; this.HelpLink = helpUrl; this.ICQErrorCode = errorCode; }
internal void TriggerStateChanged(ICQClient sender, ICQClientState oldState, Exception error) { if (this.StateChanged != null) { var eventArgs = new ICQClientStateEventArgs(oldState, sender.State, error); this.StateChanged(sender, eventArgs); } }
private static void Main() { goto X5; X1: return; #region Пример сервера OSCAR // Мы можем хранит клиентов сервера в коллекцию BlockingCollection var serverClients = new BlockingCollection<OSCAR>(); // Для приема входящих соединений используем TcpListener var server = new TcpListener(IPAddress.Any, 5555); server.Start(10); // Создадим объект OSCARCallbacks, который используется классом OSCAR // каждого соединения клиента, для вызова событий. var serverOscarEventsSet = new OSCARCallbacks { Connected = (object sender, HostConnectEventArgs e) => { /* Подключение установлено только что */ }, Disconnected = (object sender, HostErrorEventArgs e) => { /* Подключение разорванно */ }, PacketReceived = (object sender, PacketEventArgs e) => { /* Принят пакет */ ((OSCAR)sender).Send(ref e.FLAP, e.Data); Console.WriteLine("[Server] <<:: " + e.FLAP); }, // .. }; // Флаг для остановки сервера bool stopFlag = false; // Для создания сервера нам понадобится примерно вот такой метод ThreadStart serverProcessor = () => { while (!stopFlag) { // У нас есть входящие подключения на очереди? if (server.Pending()) { // Принимаем входящее подключение var socket = server.AcceptSocket(); // Создадим OSCAR для работы на этом соединении var inOscar = new OSCAR(1, serverOscarEventsSet, socket, true); serverClients.Add(inOscar); } // Выполним процессинг всех подключенных клиентов foreach (var client in serverClients) client.Process(); // CPU?! TODO test Thread.Sleep(1); } Thread.CurrentThread.Abort(); }; // Запустим сервер var serverThread = new Thread(serverProcessor); serverThread.Start(); serverThread.Priority = ThreadPriority.Highest; Thread.Sleep(1000); // Для остановки сервера может быть использован примерно такой код Action stopServerExampleCode = () => { stopFlag = true; while (serverThread.IsAlive) Thread.Sleep(100); // Обязательно завершим работу сервера server.Stop(); }; //stopServerExampleCode(); #endregion X2: return; #region Пример клиента OSCAR // Создадим объект OSCARCallbacks, который используется классом OSCAR // для вызова событий var oscarClientEvents = new OSCARCallbacks { ConnectStarted = (object sender, HostEventArgs e) => { /* Начало попытки соединения */ }, ConnectFailed = (object sender, HostErrorEventArgs e) => { /* Ошибка попытки соединения */ }, Connected = (object sender, HostConnectEventArgs e) => { /* Подключение установлено */ }, Disconnected = (object sender, HostErrorEventArgs e) => { /* Подключение разорванно */ }, PacketReceived = (object sender, PacketEventArgs e) => { /* Принят пакет */ e.FLAP.Channel++; ((OSCAR)sender).Send(ref e.FLAP, e.Data); Console.WriteLine("[Client] <<:: " + e.FLAP); }, // .. }; // Создадим экземпляр класса OSCAR для работы с сетью var oscarClient = new OSCAR(1, oscarClientEvents); // Подключим его к хосту, пример var host = new NetworkHost("localhost", 5555); oscarClient.Connect(host.EndPoint, false);//поддерживается и асинхронное подключение // Мы подключились? if (oscarClient.IsConnected) { // Запустим механизм асинхронного получения и отправки пакетов. // после этого нельзя использовать метод Receive() для получения пакета, // и более нельзя будет использовать Send() что бы отправить пакет моментально. oscarClient.RunAsyncProcessing(); // Например, отправим пакет var flap = FLAPHeader.Empty; byte[] d = Encoding.UTF8.GetBytes("Hello!"); oscarClient.Send(ref flap, d); } // Ждем нажатия Enter для завершения и выхода Console.Title = "[ENTER] to stop & exit"; Console.ReadLine(); // Отключим и уничтожим клиент if (oscarClient.IsConnected) oscarClient.Disconnect(0); oscarClient.Dispose(); // Остановим сервер stopServerExampleCode(); // Done return; #endregion X3: return; #region Пример использования OSCARUdp // Определим события для сервера var peerEventsServer = new OSCARCallbacks { Connected = (object sender, HostConnectEventArgs e) => { Console.WriteLine("[UDP Server] Accepted connection: " + e.Host); }, PacketReceived = (object sender, PacketEventArgs e) => { ((OSCARUdp)sender).Send(e.Host, e.Data); Console.WriteLine("[UDP Server] Packet from {0}, DataLength={1}", e.Host, e.Data.Length); } }; // Инициализируем пир "сервера" var peerServer = new OSCARUdp(2, peerEventsServer, true); peerServer.Start(IPAddress.Loopback);//Do not change to IPAddress.Any (only in this example) peerServer.RunAsyncProcessing(); Console.WriteLine("[UDP] Activated peerServer: " + ((IPEndPoint)peerServer.SocketBindAddress).Port); // Определим события для клиентов var peerEventsClient = new OSCARCallbacks { PacketReceived = (object sender, PacketEventArgs e) => { ((OSCARUdp)sender).Send(e.Host, e.Data); Console.WriteLine("[UDP Client] Packet: {0} DataLength={1}", e.FLAP, e.Data.Length); }, ConnectStarted = (object sender, HostEventArgs e) => { Console.WriteLine("[UDP Client] Connecting to {0}...", e.Host); }, ConnectFailed = (object sender, HostErrorEventArgs e) => { Console.WriteLine("[UDP Client] Connection failed: " + e.Error); }, Connected = (object sender, HostConnectEventArgs e) => { Console.WriteLine("[UDP Client] Connected to: " + e.Host); }, }; // Инициализируем первый пир "клиента" var peerClient = new OSCARUdp(2, peerEventsClient, false); peerClient.Start(); peerClient.RunAsyncProcessing(); Console.WriteLine("[UDP] Activated peerClient: " + ((IPEndPoint)peerClient.SocketBindAddress).Port); // Подключим еще один тестовый пир "клиента" к серверу var peerClient2 = new OSCARUdp(2, peerEventsClient, false); peerClient2.Start(); peerClient2.RunAsyncProcessing(); Console.WriteLine("[UDP] Activated peerClient2: " + ((IPEndPoint)peerClient2.SocketBindAddress).Port); // Подключим клиентов к серверу peerClient.Connect(peerServer.SocketBindAddress, false); peerClient2.Connect(peerServer.SocketBindAddress, false); // Отправим тестовое сообщение серверу var data = new byte[3000]; peerClient.Send(peerServer.SocketBindAddress, data); // Ждем нажатия Enter для завершения и выхода Console.Title = "[ENTER] to stop & exit"; Console.ReadLine(); // Остановим пиры и освободим ресурсы peerClient.Stop(); peerClient.Dispose(); peerClient2.Stop(); peerClient2.Dispose(); peerServer.Stop(); peerServer.Dispose(); #endregion X4: return; #region Пример использования ICQ Console.Write("ICQ UIN: "); var icqUin = Console.ReadLine(); Console.Write("ICQ Password: "******"{0}State changed: {1} => {2}", Environment.NewLine, e.OldState, e.NewState); if (e.Error != null) Console.WriteLine("{0}========================ERROR============================{0}{1}{0}============================{0}", Environment.NewLine, e.Error); }; // Подключимся к ICQ. icqClient.SignInAsync(); // Готово //Console.WriteLine("{0}{0}Press any key to exit.", Environment.NewLine); Console.ReadLine(); #endregion X5: #region Тестирование NetAsyncBuffer BufferPool pool = null; TcpClient tcp = null; EventHandler<SocketAsyncEventArgs> asyncOpEnd = (object sender, SocketAsyncEventArgs e) => { Console.WriteLine("Async operation finished."); pool.FreeBuffer(e); }; int bufferSize = ushort.MaxValue + FLAPHeader.FullLength; int bufferCount = 100; Console.WriteLine("Allocating buffer: x{0}*{1}...", bufferCount, bufferSize); pool = new BufferPool(asyncOpEnd, bufferSize, bufferCount); Console.WriteLine("Allocated."); Console.WriteLine("Connecting..."); tcp = new TcpClient(); tcp.Connect("login.icq.com", 5190); Console.WriteLine("ReceiveAsync called..."); tcp.Client.ReceiveAsync(pool.HoldBuffer(false, pool.BufferEntityLength)); Console.ReadLine(); #endregion }
public static void SRV_HELLO_VALIDATE(ICQClient client, ref FLAPHeader flap, byte[] packet) { if ((eFLAPChannel)flap.Channel != eFLAPChannel.NewConnection) throw new ProtocolViolationException("Unexpected server welcoming packet received; expected: SRV_HELLO"); else if (packet.Length != 4 || XBitConvert.ToUInt32(packet, 0) != 1) client.LogWrite("[WARNING] SRV_HELLO has unexpected body value or body length..."); }