TcpServer.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (c) Contributors, http://opensimulator.org/
  3. * See CONTRIBUTORS.TXT for a full list of copyright holders.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of the OpenSim Project nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
  17. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. using System;
  28. using System.IO;
  29. using System.Net;
  30. using System.Net.Sockets;
  31. using System.Threading;
  32. namespace OpenSim.ApplicationPlugins.LoadBalancer
  33. {
  34. public class StateObject
  35. {
  36. public const int BufferSize = 2048;
  37. public byte[] buffer = new byte[BufferSize];
  38. public InternalPacketHeader header = null;
  39. public MemoryStream ms_ptr = new MemoryStream();
  40. public Socket workSocket = null;
  41. }
  42. public class AsynchronousSocketListener
  43. {
  44. public static ManualResetEvent allDone = new ManualResetEvent(false);
  45. public static string data = null;
  46. #region KIRYU
  47. #region Delegates
  48. public delegate void PacketRecieveHandler(InternalPacketHeader header, byte[] buff);
  49. #endregion
  50. public static PacketRecieveHandler PacketHandler = null;
  51. #endregion
  52. public AsynchronousSocketListener()
  53. {
  54. }
  55. public static void StartListening(int port)
  56. {
  57. IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
  58. IPAddress ipAddress = ipHostInfo.AddressList[0];
  59. IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
  60. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  61. try
  62. {
  63. listener.Bind(localEndPoint);
  64. listener.Listen(100);
  65. while (true)
  66. {
  67. allDone.Reset();
  68. listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
  69. allDone.WaitOne();
  70. }
  71. }
  72. catch (Exception e)
  73. {
  74. Console.WriteLine(e.ToString());
  75. }
  76. /*
  77. Console.WriteLine("\nPress ENTER to continue...");
  78. Console.Read();
  79. */
  80. }
  81. public static void AcceptCallback(IAsyncResult ar)
  82. {
  83. allDone.Set();
  84. Socket listener = (Socket) ar.AsyncState;
  85. Socket handler = listener.EndAccept(ar);
  86. StateObject state = new StateObject();
  87. state.workSocket = handler;
  88. handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
  89. }
  90. public static void ReadCallback(IAsyncResult ar)
  91. {
  92. StateObject state = (StateObject) ar.AsyncState;
  93. Socket handler = state.workSocket;
  94. try
  95. {
  96. int bytesRead = handler.EndReceive(ar);
  97. //MainLog.Instance.Verbose("TCPSERVER", "Received packet [{0}]", bytesRead);
  98. if (bytesRead > 0)
  99. {
  100. state.ms_ptr.Write(state.buffer, 0, bytesRead);
  101. }
  102. else
  103. {
  104. //MainLog.Instance.Verbose("TCPSERVER", "Connection terminated");
  105. return;
  106. }
  107. long rest_size = state.ms_ptr.Length;
  108. long current_pos = 0;
  109. while (rest_size > TcpClient.internalPacketHeaderSize)
  110. {
  111. if ((state.header == null) && (rest_size >= TcpClient.internalPacketHeaderSize))
  112. {
  113. //MainLog.Instance.Verbose("TCPSERVER", "Processing header");
  114. // reading header
  115. state.header = new InternalPacketHeader();
  116. byte[] headerbytes = new byte[TcpClient.internalPacketHeaderSize];
  117. state.ms_ptr.Position = current_pos;
  118. state.ms_ptr.Read(headerbytes, 0, TcpClient.internalPacketHeaderSize);
  119. state.ms_ptr.Seek(0, SeekOrigin.End);
  120. state.header.FromBytes(headerbytes);
  121. }
  122. if ((state.header != null) && (rest_size >= state.header.numbytes + TcpClient.internalPacketHeaderSize))
  123. {
  124. //MainLog.Instance.Verbose("TCPSERVER", "Processing body");
  125. // reading body
  126. byte[] packet = new byte[state.header.numbytes];
  127. state.ms_ptr.Position = current_pos + TcpClient.internalPacketHeaderSize;
  128. state.ms_ptr.Read(packet, 0, state.header.numbytes);
  129. /*
  130. for (int i=0; i<state.header.numbytes; i++)
  131. {
  132. System.Console.Write(packet[i] + " ");
  133. }
  134. System.Console.WriteLine();
  135. */
  136. state.ms_ptr.Seek(0, SeekOrigin.End);
  137. // call loadbarancer function
  138. if (PacketHandler != null)
  139. {
  140. //MainLog.Instance.Verbose("TCPSERVER", "calling PacketHandler");
  141. PacketHandler(state.header, packet);
  142. }
  143. else
  144. {
  145. //MainLog.Instance.Verbose("TCPSERVER", "PacketHandler not found");
  146. }
  147. int read_size = state.header.numbytes + TcpClient.internalPacketHeaderSize;
  148. state.header = null;
  149. rest_size -= read_size;
  150. current_pos += read_size;
  151. if (rest_size < TcpClient.internalPacketHeaderSize)
  152. {
  153. byte[] rest_bytes = new byte[rest_size];
  154. state.ms_ptr.Position = read_size;
  155. state.ms_ptr.Read(rest_bytes, 0, (int) rest_size);
  156. state.ms_ptr.Close();
  157. state.ms_ptr = new MemoryStream();
  158. state.ms_ptr.Write(rest_bytes, 0, (int) rest_size);
  159. break;
  160. }
  161. }
  162. } // while (true)
  163. }
  164. catch (Exception)
  165. {
  166. //MainLog.Instance.Verbose("TCPSERVER", e.ToString());
  167. //MainLog.Instance.Verbose("TCPSERVER", e.StackTrace);
  168. }
  169. handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
  170. }
  171. }
  172. public class TcpServer
  173. {
  174. private int mPort = 11000;
  175. public TcpServer()
  176. {
  177. }
  178. public TcpServer(int port)
  179. {
  180. mPort = port;
  181. }
  182. public void start()
  183. {
  184. AsynchronousSocketListener.StartListening(mPort);
  185. }
  186. }
  187. }