Advertisement
Guest User

Client Connection

a guest
Apr 22nd, 2014
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 13.36 KB | None | 0 0
  1. // Copyright (C) Paul Becker, - All Rights Reserved
  2. // Unauthorized copying of this file, via any medium is strictly prohibited
  3. // Proprietary and confidential
  4. // Written by Paul Becker <paul.becker1@gmx.de>, 08:13
  5.  
  6. #region usings
  7.  
  8. using System;
  9. using System.Collections.Generic;
  10. using System.IO;
  11. using System.Net;
  12. using System.Net.Sockets;
  13. using Assets.Model.Player;
  14. using Assets.Network.Packets;
  15.  
  16. #endregion
  17.  
  18. namespace Assets.Network
  19. {
  20.     public class Connection : IDisposable
  21.     {
  22.         private readonly Queue<PacketToServer> PacketSendQueue = new Queue<PacketToServer>();
  23.         private readonly MemoryStream ReceiveStream;
  24.         private long AverageUpstream;
  25.         protected DateTime LastUpdate;
  26.         private bool ReadInterestEnabled;
  27.         protected bool Ready = false;
  28.         protected byte[] ReceiveBuffer;
  29.         protected DateTime RevDate = DateTime.Now;
  30.  
  31.         private bool WriteInterestEnabled;
  32.         protected TcpClient client;
  33.         public Player owner;
  34.  
  35.  
  36.         public Connection(TcpClient c)
  37.         {
  38.             client = c;
  39.             ReceiveBuffer = new byte[8192];
  40.             ReceiveStream = new MemoryStream(8192*4);
  41.         }
  42.  
  43.         public long OldValue { get; set; }
  44.  
  45.         public void SetClient(TcpClient client)
  46.         {
  47.             this.client = client;
  48.         }
  49.  
  50.         public string GetRemoteIP()
  51.         {
  52.             return ((IPEndPoint) client.Client.RemoteEndPoint).Address.ToString();
  53.         }
  54.  
  55.         public void Close()
  56.         {
  57.             OnDisconnect();
  58.             client.Close();
  59.         }
  60.  
  61.         public virtual void OnConnect()
  62.         {
  63.             BeginRead();
  64.             UnityEngine.Debug.Log("New Connection from " + GetRemoteIP());
  65.         }
  66.  
  67.         private void BeginRead()
  68.         {
  69.             if (client != null && client.Client != null && client.Connected)
  70.             {
  71.                 try
  72.                 {
  73.                     UnityEngine.Debug.Log("BeginRead");
  74.                     client.Client.BeginReceive(ReceiveBuffer, 0, 8192, SocketFlags.None, EndRead, ReceiveBuffer);
  75.                 }
  76.                 catch (Exception)
  77.                 {
  78.                     Close();
  79.                     UnityEngine.Debug.Log("Close BeginRead");
  80.                 }
  81.             }
  82.             else
  83.             {
  84.                 UnityEngine.Debug.Log("Readíng wont work due no Connection");
  85.             }
  86.         }
  87.  
  88.         public virtual void OnDisconnect()
  89.         {
  90.         }
  91.  
  92.         private void EnableReadInterest()
  93.         {
  94.             if (ReadInterestEnabled)
  95.                 return;
  96.             lock (ReceiveStream)
  97.             {
  98.                 ReadInterestEnabled = true;
  99.                 UnityEngine.Debug.Log("EnableReadInterest");
  100.                 // Read First Packet Size then go back at initial position.
  101.                 var size =
  102.                     BitConverter.ToUInt16(new[] {(byte) ReceiveStream.ReadByte(), (byte) ReceiveStream.ReadByte()}, 0);
  103.                 ReceiveStream.Position -= 2;
  104.  
  105.                 while (size > 0 && size <= (ReceiveStream.Length - ReceiveStream.Position))
  106.                 {
  107.                     //UnityEngine.Debug.Log("Read: " + size + "-byte packet.");
  108.  
  109.                     // Read Packet Data including length
  110.                     var data = new byte[size];
  111.                     ReceiveStream.Read(data, 0, size);
  112.                     // Process packet.
  113.  
  114.                     using (var stream = new MemoryStream(data, 2, data.Length - 2, false))
  115.                     {
  116.                         using (var rd = new BinaryReader(stream))
  117.                         {
  118.                             var opcode = 0;
  119.  
  120.                             opcode = rd.ReadByte() & 0xff;
  121.  
  122.  
  123.                             Type packetType = null;
  124.                             PacketHolder.PacketsFromServer.TryGetValue(opcode, out packetType);
  125.  
  126.                             if (packetType == null)
  127.                             {
  128.                                 UnityEngine.Debug.Log("Unknown packet received from AION client, opcode: " +
  129.                                                       string.Format("{0:X}", opcode) + " - size: " + (size - 2));
  130.                             }
  131.                             else
  132.                             {
  133.                                 var pkt = (PacketFromServer) Activator.CreateInstance(packetType);
  134.                                 pkt.Write(stream.ToArray(), (int) stream.Position,
  135.                                     (int) (stream.Length - stream.Position));
  136.                                 pkt.Position = 0;
  137.                                 stream.Close();
  138.  
  139.                                 UnityEngine.Debug.Log("PktRecv " + GetRemoteIP() + ": " + pkt.GetType().Name + "(" +
  140.                                                       pkt.Length +
  141.                                                       ")");
  142.                                 pkt.Connection = this;
  143.                                 pkt.Opcode = opcode;
  144.  
  145.                                 try
  146.                                 {
  147.                                     pkt.ProcessPacket();
  148.                                 }
  149.                                 catch (Exception e)
  150.                                 {
  151.                                     UnityEngine.Debug.Log(
  152.                                         String.Format("Cannot process client packet!\nException -> {0}", e));
  153.                                 }
  154.  
  155.                                 pkt.Close();
  156.                             }
  157.  
  158.                             if (ReceiveStream.Length - ReceiveStream.Position > 2)
  159.                             {
  160.                                 size =
  161.                                     BitConverter.ToUInt16(
  162.                                         new[] {(byte) ReceiveStream.ReadByte(), (byte) ReceiveStream.ReadByte()}, 0);
  163.                                 ReceiveStream.Position -= 2;
  164.                             }
  165.                             else
  166.                                 size = 0;
  167.                         }
  168.  
  169.                         var remaining = (int) (ReceiveStream.Length - ReceiveStream.Position);
  170.                         if (remaining > 0)
  171.                         {
  172.                             // Read Latest Bytes
  173.                             var remdata = new byte[remaining];
  174.                             ReceiveStream.Read(remdata, 0, remaining);
  175.                             ReceiveStream.Position = 0;
  176.                             ReceiveStream.Write(remdata, 0, remdata.Length);
  177.                         }
  178.                         else
  179.                             ReceiveStream.Position = 0;
  180.                     }
  181.                     ReadInterestEnabled = false;
  182.                 }
  183.             }
  184.         }
  185.  
  186.         private void EndRead(IAsyncResult result)
  187.         {
  188.             lock (ReceiveBuffer)
  189.             {
  190.                 try
  191.                 {
  192.                     var received = 0;
  193.  
  194.                     try
  195.                     {
  196.                         UnityEngine.Debug.Log("EndRead");
  197.                         received = client.Client.EndReceive(result);
  198.                     }
  199.                     catch (Exception)
  200.                     {
  201.                         OnDisconnect();
  202.                         return;
  203.                     }
  204.  
  205.                     if (received <= 0)
  206.                     {
  207.                         OnDisconnect();
  208.                         return;
  209.                     }
  210.  
  211.                     if (!Ready)
  212.                     {
  213.                         UnityEngine.Debug.Log("Received a " + received +
  214.                                               "-byte packet while connection not ready to accept packets.");
  215.                         return;
  216.                     }
  217.  
  218.                     // This is the full set of data.
  219.                     // May contain several packets.
  220.                     var data = (byte[]) result.AsyncState;
  221.  
  222.                     lock (ReceiveStream)
  223.                     {
  224.                         ReceiveStream.Write(data, 0, received);
  225.                     }
  226.  
  227.                     if (!ReadInterestEnabled)
  228.                     {
  229.                         ReceiveStream.SetLength(ReceiveStream.Position);
  230.                         ReceiveStream.Position = 0;
  231.                         EnableReadInterest();
  232.                     }
  233.                 }
  234.                 catch (Exception e)
  235.                 {
  236.                     UnityEngine.Debug.Log("Error while processing client data! Exception " + e.Message);
  237.                 }
  238.                 BeginRead();
  239.             }
  240.         }
  241.  
  242.         public void SendPacket(PacketToServer packet)
  243.         {
  244.             if (client == null)
  245.             {
  246.                 UnityEngine.Debug.LogWarning("Tried to send Pkt without Connection to the Masterserver");
  247.                 return;
  248.             }
  249.             lock (PacketSendQueue)
  250.             {
  251.                 PacketSendQueue.Enqueue(packet);
  252.                 if (!WriteInterestEnabled)
  253.                     EnableWriteInterest();
  254.             }
  255.         }
  256.  
  257.         public void SendPacket(PacketToServer packet, bool closeAfterPacket)
  258.         {
  259.             SendPacket(packet);
  260.             if (closeAfterPacket)
  261.                 SendPacket(null);
  262.         }
  263.  
  264.         private void EnableWriteInterest()
  265.         {
  266.             WriteInterestEnabled = true;
  267.             while (PacketSendQueue.Count > 0)
  268.             {
  269.                 var pkt = PacketSendQueue.Dequeue();
  270.                 if (pkt == null)
  271.                 {
  272.                     Close();
  273.                     UnityEngine.Debug.LogWarning("Closing Connection");
  274.                     return;
  275.                 }
  276.                 BeginWrite(pkt);
  277.             }
  278.             WriteInterestEnabled = false;
  279.         }
  280.  
  281.         protected void BeginWrite(PacketToServer packet)
  282.         {
  283.             if (packet == null)
  284.                 return;
  285.             try
  286.             {
  287.                 // Here, packet is ready to be sent
  288.                 packet.Connection = this;
  289.                 packet.Position = 0;
  290.  
  291.                 if (!PacketHolder.PacketsToServer.ContainsKey(packet.GetType()))
  292.                 {
  293.                     UnityEngine.Debug.Log("No opcode defined for " + packet.GetType().Name);
  294.                     return;
  295.                 }
  296.                 var opcode = 0;
  297.                 PacketHolder.PacketsToServer.TryGetValue(packet.GetType(), out opcode);
  298.  
  299.                 packet.Opcode = opcode;
  300.  
  301.                 packet.WriteShort(0); // Future length
  302.  
  303.  
  304.                 packet.WriteByte((byte) opcode); // Opcode
  305.                 packet.WritePacket(); // Write contents of packet
  306.  
  307.                 var length = (int) packet.Position;
  308.  
  309.                 byte[] result;
  310.                 result = new byte[length];
  311.  
  312.  
  313.                 Array.Copy(packet.ToArray(), 0, result, 0, length);
  314.  
  315.  
  316.                 packet.Position = 0;
  317.                 packet.WriteShort((short) length);
  318.                 packet.Write(result, 2, length - 2);
  319.  
  320.                 // Send in socket
  321.                 lock (client)
  322.                 {
  323.                     client.Client.BeginSend(packet.ToArray(), 0, length, SocketFlags.None, EndWrite, packet);
  324.                 }
  325.                 if (!Ready)
  326.                     Ready = true;
  327.             }
  328.             catch (Exception e)
  329.             {
  330.                 UnityEngine.Debug.Log(DateTime.Now.ToLongTimeString() + " : Error while writing to data sink!" +
  331.                                       e.Message);
  332.                 UnityEngine.Debug.LogWarning(client.Connected);
  333.             }
  334.         }
  335.  
  336.         private void EndWrite(IAsyncResult result)
  337.         {
  338.             UnityEngine.Debug.Log(DateTime.Now.ToLongTimeString() + " : Entering EndWrite Area");
  339.             if (client != null && client.Client != null && client.Client.Connected)
  340.             {
  341.                 var sent = client.Client.EndSend(result);
  342.                 var pkt = (PacketToServer) result.AsyncState;
  343.                 if (owner.ShowNetworkStat)
  344.                 {
  345.                     LastUpdate = DateTime.Now;
  346.                     AverageUpstream += pkt.Length;
  347.                     var interval = LastUpdate - RevDate;
  348.                     if (interval.TotalSeconds >= owner.ShowStatIntervall)
  349.                     {
  350.                         RevDate = DateTime.Now;
  351.                         AverageUpstream = 0;
  352.                         OldValue = AverageUpstream;
  353.                     }
  354.                 }
  355.                 UnityEngine.Debug.Log(DateTime.Now.ToLongTimeString() + " : PktSend " + GetRemoteIP() + ": " +
  356.                                       pkt.GetType().Name + " (" + pkt.Length +
  357.                                       ") Opcode: " +
  358.                                       pkt.Opcode);
  359.             }
  360.             else
  361.             {
  362.                 UnityEngine.Debug.Log(String.Format("{0},{1},{2}", client != null, client.Client != null,
  363.                     client.Client.Connected));
  364.             }
  365.         }
  366.  
  367.         public void PrintUpstreamToServer(int intervall)
  368.         {
  369.             UnityEngine.Debug.Log(String.Format("{0} -> {1}bytes Upstream in the last {2} seconds",
  370.                 DateTime.Now.ToLongTimeString(), OldValue, intervall));
  371.         }
  372.  
  373.         #region IDisposable Member
  374.  
  375.         public void Dispose()
  376.         {
  377.             ReceiveStream.Dispose();
  378.             PacketSendQueue.Clear();
  379.         }
  380.  
  381.         #endregion
  382.     }
  383. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement