/// <summary> /// Sends a keepalive packet (FLAP channel 5) /// </summary> /// <param name="threadstate">Always <c>null</c></param> private void SendKeepalive(object threadstate) { using (ByteStream stream = new ByteStream()) { FLAPHeader fh; fh.Channel = 0x05; fh.DatagramSequenceNumber = 0; fh.DataSize = 0; stream.PrependOscarHeaders(fh, null); try { byte[] keepalive = stream.GetBytes(); Marshal.InsertUshort(keepalive, (ushort)FLAPSequence, 2); lock (socket) { socket.Write(keepalive); } Logging.WriteString("Sent keepalive over connection {0}", ID); } catch (Exception ex) { if (!isDisconnecting) { Logging.WriteString("Couldn't send keepalive: {0}, connection {1}", ex.Message, ID); DisconnectFromServer(true); } } keepAliveTimer.Change(60000, Timeout.Infinite); } }
/// <summary> /// This method is invoked when the connection is complete /// </summary> protected virtual void OnConnectionFinished() { Connecting = true; // Read in the first ten bytes (6 byte FLAP channel 0x01 + 0x00000001) // of the connection handshake byte[] serverhandshake = new byte[10]; try { int bytesreceived = 0; int receiveindex = 0; lock (socket) { while (bytesreceived < 10) { bytesreceived = socket.Read(serverhandshake, receiveindex, 10 - receiveindex); receiveindex += bytesreceived; } } } catch (Exception ex) { Logging.WriteString("Can't read handshake from server: {0}, connection {1}", ex.Message, ID); DisconnectFromServer(true); return; } finally { serverhandshake = null; } // Construct our reply to the connection handshake using (ByteStream clientHandshake = new ByteStream()) { FLAPHeader fh; fh.Channel = 0x01; fh.DatagramSequenceNumber = FLAPSequence; fh.DataSize = (ushort)(4 + ((cookie == null) ? 0 : 4 + cookie.GetByteCount())); clientHandshake.PrependOscarHeaders(fh, null); clientHandshake.WriteUint(Constants.PROTOCOL_VERSION); if (cookie != null) { clientHandshake.WriteUshort(0x0006); clientHandshake.WriteUshort((ushort)cookie.GetByteCount()); clientHandshake.WriteByteArray(cookie.ToByteArray()); } try { lock (socket) { socket.Write(clientHandshake.GetBytes()); } } catch (Exception ex) { Logging.WriteString("Couldn't send handshake to server: {0}, connection {1}", ex.Message, ID); DisconnectFromServer(true); return; } } StopTimeoutPeriod(); Connecting = true; // And the handshaking is done. Auth connection will send // SNAC(17,06) and any other connection will receive SNAC(01,03) OnServerConnectionCompleted(); }