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 }
private void ConnectInitSession(NetworkHost bossHost, byte[] bossCookie) { // Begin second stage connecting ICQ network this.LogWrite("Connecting to ICQ BOSS."); this.Connection.Connect(bossHost.EndPoint, false); this.LogWrite("Connected to host({0})", bossHost.Address); // Define our packet read timeout const int readTimeout = (int)TimeSpan.TicksPerSecond * 5; // Expect: SRV_HELLO var flap = FLAPHeader.Empty; byte[] packet = null; if (!this.Connection.Receive(ref flap, out packet, true, readTimeout)) throw new TimeoutException("Server did not reply in proper time, expected: SRV_HELLO"); ICQ.Packets.SRV_HELLO_VALIDATE(this, ref flap, packet); // Reply with: CLI_HELLO, containing BOSS cookie ICQ.Packets.CLI_HELLO_BOSS(ref flap, ref packet, bossCookie); this.Connection.Send(ref flap, packet); // Expect: SRV_SERVICE_LIST_ENUM if (!this.Connection.Receive(ref flap, out packet, true, readTimeout)) throw new TimeoutException("Server did not reply in proper time, expected: SRV_CHALLENGE_REPLY or SRV_AUTH_RESPONSE"); else if (!flap.IsSNAC) throw new ProtocolViolationException("Expected SNAC, got packet: " + flap); var snac = (SNAC)packet; if (snac.Type != ICQ.Packets.SRV_SERVICE_LIST_ENUM) throw new ProtocolViolationException("Unexpected SNAC received, expected: SRV_SERVICE_LIST_ENUM, got: " + snac.Type); else { throw new ApplicationException(); } throw new NotImplementedException(); }