Advertisement
diondokter

NetworkClient

Jul 31st, 2014
434
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 8.41 KB | None | 0 0
  1. public class NetworkClient : IDisposable //Every connection is a NetworkClient. This class makes use of of predefined message classes, all derived from "GenericMessage". "RequestMessage" and "ResponseMessage" are also derived from "GenericMessage". The way I implemented this system creates the possibility to have an request-response system making syncronization relative easy.
  2. {
  3.     public TcpClient TcpSocket;
  4.     public NetworkStream Stream;
  5.     private List<int> RequestIDs = new List<int>();
  6.     private List<ResponseMessage> Responses = new List<ResponseMessage>();
  7.     public UdpClient UdpListener;
  8.     public int TcpPing
  9.     {
  10.         get;
  11.         private set;
  12.     }
  13.     public int UdpPing
  14.     {
  15.         get;
  16.         private set;
  17.     }
  18.     public long RealPing
  19.     {
  20.         get
  21.         {
  22.             System.Net.NetworkInformation.Ping P = new System.Net.NetworkInformation.Ping();
  23.             System.Net.NetworkInformation.PingReply Reply = P.Send(IP, 3000);
  24.             return Reply.RoundtripTime;
  25.         }
  26.     }
  27.  
  28.     public IPAddress IP
  29.     {
  30.         get
  31.         {
  32.             return ((IPEndPoint)TcpSocket.Client.RemoteEndPoint).Address;
  33.         }
  34.     }
  35.  
  36.     public NetworkClient()
  37.     {
  38.  
  39.     }
  40.     public NetworkClient(TcpClient Socket) //Needs a connected tcp socket
  41.     {
  42.         this.TcpSocket = Socket;
  43.         Socket.NoDelay = true;
  44.         Stream = Socket.GetStream();
  45.  
  46.         UdpListener = new UdpClient(AddressFamily.InterNetwork);
  47.         UdpListener.ExclusiveAddressUse = false;
  48.         UdpListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
  49.         UdpListener.Client.Bind(new IPEndPoint(IP, Connection.CurrentPort - 1));
  50.         UdpListener.Connect(IP, Connection.CurrentPort);
  51.     }
  52.     public NetworkClient(TcpClient Socket, NetworkStream Stream)
  53.     {
  54.         this.TcpSocket = Socket;
  55.         Socket.NoDelay = true;
  56.         this.Stream = Stream;
  57.  
  58.         UdpListener = new UdpClient(AddressFamily.InterNetwork);
  59.         UdpListener.ExclusiveAddressUse = false;
  60.         UdpListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
  61.         UdpListener.Client.Bind(new IPEndPoint(IP, Connection.CurrentPort - 1));
  62.         UdpListener.Connect(IP, Connection.CurrentPort);
  63.     }
  64.     public NetworkClient(NetworkClient OriginalClient)
  65.     {
  66.         this.TcpSocket = OriginalClient.TcpSocket;
  67.         this.Stream = OriginalClient.Stream;
  68.  
  69.         UdpListener = new UdpClient(AddressFamily.InterNetwork);
  70.         UdpListener.ExclusiveAddressUse = false;
  71.         UdpListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
  72.         UdpListener.Client.Bind(new IPEndPoint(IP, Connection.CurrentPort - 1));
  73.         UdpListener.Connect(IP, Connection.CurrentPort);
  74.     }
  75.  
  76.     public void SendTcp(GenericMessage Message)
  77.     {
  78.         try
  79.         {
  80.             Message.SendTime = DateTime.UtcNow;
  81.             List<byte> Bytes = ClassToBytes(Message).ToList();
  82.             Bytes.InsertRange(0, (BitConverter.GetBytes((int)Bytes.Count)));
  83.             Stream.Write(Bytes.ToArray(), 0, Bytes.Count);
  84.         }
  85.         catch (IOException e)
  86.         {
  87.             Main_Form.MainForm.ConsoleWriter(e);
  88.         }
  89.     }
  90.  
  91.     public ResponseMessage SendTcp(RequestMessage Message, bool WaitForResponse)
  92.     {
  93.         for (int i = 1; i < int.MaxValue; i++)
  94.         {
  95.             if (!RequestIDs.Contains(i))
  96.             {
  97.                 RequestIDs.Add(i);
  98.                 Message.ID = i;
  99.                 break;
  100.             }
  101.         }
  102.  
  103.         SendTcp((GenericMessage)Message);
  104.  
  105.         if (WaitForResponse)
  106.         {
  107.             DateTime EndTime = DateTime.UtcNow.Add(new TimeSpan(0, 0, 5));
  108.             while (EndTime > DateTime.UtcNow)
  109.             {
  110.                 foreach (ResponseMessage BufferedResponse in Responses)
  111.                 {
  112.                     if (BufferedResponse.ID == Message.ID)
  113.                     {
  114.                         RequestIDs.Remove(Message.ID);
  115.                         ResponseMessage Response = BufferedResponse;
  116.                         Responses.Remove(Response);
  117.                         return Response;
  118.                     }
  119.                 }
  120.                 Thread.Sleep(5);
  121.             }
  122.  
  123.             throw new TimeoutException("An expected response was never received.");
  124.         }
  125.         else
  126.         {
  127.             return null;
  128.         }
  129.     }
  130.  
  131.     public void SendUdp(GenericMessage Message)
  132.     {
  133.         Message.SendTime = DateTime.UtcNow;
  134.         List<byte> Bytes = ClassToBytes(Message).ToList();
  135.         Bytes.InsertRange(0, (BitConverter.GetBytes((int)Bytes.Count)));
  136.         UdpListener.Send(Bytes.ToArray(), Bytes.Count);
  137.     }
  138.  
  139.     public ResponseMessage SendUdp(RequestMessage Message, bool WaitForResponse)
  140.     {
  141.         for (int i = 1; i < int.MaxValue; i++)
  142.         {
  143.             if (!RequestIDs.Contains(i))
  144.             {
  145.                 RequestIDs.Add(i);
  146.                 Message.ID = i;
  147.                 break;
  148.             }
  149.         }
  150.  
  151.         SendUdp((GenericMessage)Message);
  152.  
  153.         if (WaitForResponse)
  154.         {
  155.             DateTime EndTime = DateTime.UtcNow.Add(new TimeSpan(0, 0, 5));
  156.             while (EndTime > DateTime.UtcNow)
  157.             {
  158.                 foreach (ResponseMessage BufferedResponse in Responses)
  159.                 {
  160.                     if (BufferedResponse.ID == Message.ID)
  161.                     {
  162.                         RequestIDs.Remove(Message.ID);
  163.                         ResponseMessage Response = BufferedResponse;
  164.                         Responses.Remove(Response);
  165.                         return Response;
  166.                     }
  167.                 }
  168.                 Thread.Sleep(5);
  169.             }
  170.  
  171.             throw new TimeoutException("An expected response was never received.");
  172.         }
  173.         else
  174.         {
  175.             return null;
  176.         }
  177.     }
  178.  
  179.     public GenericMessage TcpReceive()
  180.     {
  181.         if (Stream.DataAvailable)
  182.         {
  183.             byte[] Buffer = new byte[sizeof(int)];
  184.             Stream.Read(Buffer, 0, sizeof(int));
  185.             int MessageLenght = BitConverter.ToInt32(Buffer, 0);
  186.             byte[] Message = new byte[MessageLenght];
  187.  
  188.             int BytesRead = 0;
  189.             while (BytesRead < MessageLenght)
  190.             {
  191.                 BytesRead += Stream.Read(Message, BytesRead, MessageLenght - BytesRead);
  192.                 Thread.Sleep(0);
  193.             }
  194.  
  195.             GenericMessage ReceivedMessage = BytesToClass(Message);
  196.             ReceivedMessage.ReceiveTime = DateTime.UtcNow;
  197.             TcpPing = (int)(DateTime.UtcNow - ReceivedMessage.SendTime).Milliseconds * 2; //Times two because a normal ping indicates a round-trip time and mine is base on a single trip
  198.  
  199.             if (ReceivedMessage is ResponseMessage)
  200.             {
  201.                 if (RequestIDs.Contains(((ResponseMessage)ReceivedMessage).ID))
  202.                 {
  203.                     Responses.Add((ResponseMessage)ReceivedMessage);
  204.                 }
  205.                 return null;
  206.             }
  207.             else
  208.             {
  209.                 return ReceivedMessage;
  210.             }
  211.         }
  212.         else
  213.         {
  214.             return null;
  215.         }
  216.     }
  217.  
  218.     public GenericMessage UdpReceive()
  219.     {
  220.         if (UdpListener.Available > 0)
  221.         {
  222.             IPEndPoint IpEnd = new IPEndPoint(IPAddress.Any, 0);
  223.  
  224.             List<byte> Message = UdpListener.Receive(ref IpEnd).ToList();
  225.             Message.RemoveRange(0, sizeof(int));
  226.  
  227.             GenericMessage ReceivedMessage = BytesToClass(Message.ToArray());
  228.  
  229.             if (!IpEnd.Address.Equals(IP))
  230.             {
  231.                 return null;
  232.             }
  233.  
  234.             ReceivedMessage.ReceiveTime = DateTime.UtcNow;
  235.             UdpPing = (int)(DateTime.UtcNow - ReceivedMessage.SendTime).Milliseconds * 2; //Times two because a normal ping indicates a round-trip time and mine is base on a single trip
  236.  
  237.             if (ReceivedMessage is ResponseMessage)
  238.             {
  239.                 if (RequestIDs.Contains(((ResponseMessage)ReceivedMessage).ID))
  240.                 {
  241.                     Responses.Add((ResponseMessage)ReceivedMessage);
  242.                 }
  243.                 return null;
  244.             }
  245.             else
  246.             {
  247.                 return ReceivedMessage;
  248.             }
  249.         }
  250.         else
  251.         {
  252.             return null;
  253.         }
  254.     }
  255.     public void CloseConnection()
  256.     {
  257.         UdpListener.Close();
  258.         Stream.Close();
  259.         TcpSocket.Close();
  260.     }
  261.  
  262.     public static byte[] ClassToBytes(GenericMessage Data)
  263.     {
  264.         BinaryFormatter Formatter = new BinaryFormatter();
  265.         Formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
  266.         MemoryStream Stream = new MemoryStream();
  267.         Formatter.Serialize(Stream, Data);
  268.         return Stream.ToArray();
  269.     }
  270.  
  271.     public static GenericMessage BytesToClass(byte[] Data)
  272.     {
  273.         BinaryFormatter Formatter = new BinaryFormatter();
  274.         Formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple;
  275.         Formatter.Binder = new FormatterBinder();
  276.         MemoryStream Stream = new MemoryStream(Data);
  277.         return (GenericMessage)Formatter.Deserialize(Stream);
  278.     }
  279.  
  280.     bool Disposed;
  281.     public void Dispose()
  282.     {
  283.         Dispose(true);
  284.     }
  285.     protected virtual void Dispose(bool Disposing)
  286.     {
  287.         if (Disposed)
  288.         {
  289.             return;
  290.         }
  291.  
  292.         if (Disposing)
  293.         {
  294.             Disposed = true;
  295.             CloseConnection();
  296.         }
  297.     }
  298.  
  299.     /// <summary>
  300.     /// This makes sure that the formatted binaries won't whine about the different assemblies
  301.     /// </summary>
  302.     private sealed class FormatterBinder : SerializationBinder
  303.     {
  304.         public override Type BindToType(string assemblyName, string typeName)
  305.         {
  306.             Type typeToDeserialize = null;
  307.             // For each assemblyName/typeName that you want to deserialize to
  308.             // a different type, set typeToDeserialize to the desired type.
  309.             String exeAssembly = Assembly.GetExecutingAssembly().FullName;
  310.  
  311.             // The following line of code returns the type.
  312.             typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, exeAssembly));
  313.             return typeToDeserialize;
  314.         }
  315.     }
  316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement