PageRenderTime 51ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/CounterStrikeLive/CounterStrikeLive/ServiceClient/Providers/SocketsProvider.cs

#
C# | 358 lines | 162 code | 55 blank | 141 comment | 18 complexity | 96132e3f0d883330921313cc935ec0a8 MD5 | raw file
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Threading;
  5. using System.IO;
  6. using System.Xml.Serialization;
  7. using System.Text;
  8. using System.Windows.Threading;
  9. using System.Windows;
  10. using System.Windows.Controls;
  11. using System.Collections.Generic;
  12. using System.Xml;
  13. using System.Linq;
  14. using System.Runtime.Serialization;
  15. namespace CounterStrikeLive.ServiceClient
  16. {
  17. public partial class SocketsProvider : ServiceClientProvider
  18. {
  19. private const int ResponseBufferSize = 512;
  20. private Socket socket;
  21. private DnsEndPoint endPoint;
  22. private Dispatcher _owner;
  23. private bool Initialized = false;
  24. private object initData = null;
  25. private List<string> MessagesToProcess = null;
  26. private object receiveLock = new object();
  27. private static object sendLock = new object();
  28. private static object onSendLock = new object();
  29. MemoryStream stream = null;
  30. private static bool ReceiveThreadBusy = false;
  31. public SocketsProvider(string host, int port)
  32. {
  33. //_owner = UIElement.Dispatcher;
  34. endPoint = new DnsEndPoint(host, port, AddressFamily.InterNetwork);
  35. MessagesToProcess = new List<string>();
  36. stream = new MemoryStream();
  37. }
  38. public bool IsConnected
  39. {
  40. get
  41. {
  42. if (socket == null) return false;
  43. return socket.Connected;
  44. }
  45. }
  46. public void Start()
  47. {
  48. SocketAsyncEventArgs args = new SocketAsyncEventArgs();
  49. args.UserToken = socket;
  50. args.RemoteEndPoint = endPoint;
  51. args.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
  52. socket = new Socket(AddressFamily.InterNetwork,
  53. SocketType.Stream, ProtocolType.Tcp);
  54. socket.ConnectAsync(args);
  55. if (args.SocketError != SocketError.Success)
  56. throw new SocketException((int)args.SocketError);
  57. }
  58. private void OnConnect(object sender, SocketAsyncEventArgs e)
  59. {
  60. bool isConnected = (e.SocketError == SocketError.Success);
  61. //if (isConnected)
  62. //{
  63. // XmlSerializer xs = new XmlSerializer(typeof(LoginRequestInfo));
  64. // string Data = Commons.Serialize(xs, _info);
  65. // SendMessage(Data);
  66. //}
  67. if (isConnected)
  68. {
  69. Initialized = true;
  70. SendMessage(initData);
  71. //_owner.BeginInvoke(
  72. // delegate
  73. // {
  74. // if (ConnectFailed != null)
  75. // {
  76. // ConnectFailed(this, new EventArgs());
  77. // }
  78. // });
  79. }
  80. }
  81. protected override void SendMessage(object data)
  82. {
  83. if (data == null) return;
  84. if (!Initialized)
  85. {
  86. initData = data;
  87. Start();
  88. }
  89. else
  90. {
  91. if (IsConnected)
  92. {
  93. //lock (sendLock)
  94. {
  95. //MemoryStream stream = new MemoryStream();
  96. //DataContractSerializer dcs = new DataContractSerializer(typeof(object), KnownTypes.Get());
  97. //dcs.WriteObject(stream, data);
  98. //stream.Position = 0;
  99. //StreamReader reader = new StreamReader(stream);
  100. //string xmlData = reader.ReadToEnd();
  101. //List<byte> bytes = new List<byte>();
  102. //bytes.AddRange(BitConverter.GetBytes(xmlData.Length));
  103. //bytes.AddRange(Encoding.UTF8.GetBytes(xmlData));
  104. //SocketAsyncEventArgs args = new SocketAsyncEventArgs();
  105. //args.SetBuffer(bytes.ToArray(), 0, bytes.Count);
  106. //args.UserToken = socket;
  107. //args.RemoteEndPoint = endPoint;
  108. //args.Completed -= new EventHandler<SocketAsyncEventArgs>(OnConnect);
  109. //args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
  110. //socket.SendAsync(args);
  111. }
  112. }
  113. else
  114. {
  115. //uiThread.Post(CallConnectionFailedEvent, null);
  116. }
  117. }
  118. }
  119. #region Events
  120. private void OnSend(object sender, SocketAsyncEventArgs e)
  121. {
  122. if (e.SocketError == SocketError.Success)
  123. {
  124. if (e.LastOperation == SocketAsyncOperation.Send)
  125. {
  126. // Prepare receiving.
  127. //lock (onSendLock)
  128. {
  129. Socket s = e.UserToken as Socket;
  130. byte[] response = new byte[ResponseBufferSize];
  131. e.SetBuffer(response, 0, response.Length);
  132. e.Completed -= new EventHandler<SocketAsyncEventArgs>(OnSend);
  133. e.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
  134. s.ReceiveAsync(e);
  135. }
  136. }
  137. }
  138. else
  139. {
  140. //uiThread.Post(CallConnectionFailedEvent, null);
  141. }
  142. }
  143. //private void ParseStream(Stream stream)
  144. //{
  145. // string frame = string.Empty;
  146. // if (stream.Length > 0)
  147. // {
  148. // int size = TryParseSize(stream);
  149. // if (size > 0)
  150. // {
  151. // frame = TryParseFrame(stream, size);
  152. // if (!string.IsNullOrEmpty(frame))
  153. // {
  154. // MessagesToProcess.Add(frame);
  155. // }
  156. // }
  157. // }
  158. // if (stream.Length > 0 && !string.IsNullOrEmpty(frame))
  159. // {
  160. // stream.Position = 0;
  161. // ParseStream(stream);
  162. // }
  163. //}
  164. //private int TryParseSize(Stream stream)
  165. //{
  166. // int size = -1;
  167. // if (stream.Length >= 4)
  168. // {
  169. // byte[] buffer = new byte[4];
  170. // stream.Read(buffer, 0, buffer.Length);
  171. // size = BitConverter.ToInt32(buffer, 0);
  172. // stream.Position -= buffer.Length;
  173. // if (size > 100000)
  174. // {
  175. // uiThread.Post(delegate(object obj)
  176. // {
  177. // Application.Log((string)obj);
  178. // }, "Message size " + size.ToString() + " is too big." + Environment.NewLine +
  179. // "Fatal communication error!");
  180. // //throw new Exception("Message size " + size.ToString() + " is too big." + Environment.NewLine +
  181. // // "Fatal communication error!");
  182. // }
  183. // }
  184. // return size;
  185. //}
  186. //private string TryParseFrame(Stream stream, int Size)
  187. //{
  188. // string frame = string.Empty;
  189. // Size += 4;
  190. // if (stream.Length - stream.Position >= Size)
  191. // {
  192. // byte[] buffer = new byte[Size - 4];
  193. // stream.Position = 4;
  194. // stream.Read(buffer, 0, buffer.Length);
  195. // frame = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
  196. // // Trim stream
  197. // byte[] byteBuffer = new byte[stream.Length];
  198. // stream.Position = 0;
  199. // stream.Read(byteBuffer, 0, byteBuffer.Length);
  200. // stream.SetLength(0);
  201. // List<byte> bytes = new List<byte>(byteBuffer).GetRange(Size, byteBuffer.Length - Size);
  202. // stream.Write(bytes.ToArray(), 0, bytes.Count);
  203. // }
  204. // return frame;
  205. //}
  206. private void OnReceive(object sender, SocketAsyncEventArgs e)
  207. {
  208. //uiThread.Post(delegate(object obj)
  209. //{
  210. // Commons.Storage.Log((string)obj);
  211. //}, "Enter OnReceive before lock");
  212. lock (stream)
  213. {
  214. if (ReceiveThreadBusy)
  215. {
  216. //uiThread.Post(delegate(object obj)
  217. //{
  218. // Application.Log((string)obj);
  219. //}, "Stream concurrent access error.");
  220. }
  221. ReceiveThreadBusy = true;
  222. //uiThread.Post(delegate(object obj)
  223. //{
  224. // Commons.Storage.Log((string)obj);
  225. //}, "Enter OnReceive after lock");
  226. // string str = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
  227. try
  228. {
  229. //stream.SetLength(stream.Length + e.BytesTransferred);
  230. //stream.Position = stream.Length - e.BytesTransferred;
  231. //stream.Write(e.Buffer, 0, e.BytesTransferred);
  232. //stream.Position = 0;
  233. //ParseStream(stream);
  234. //while (MessagesToProcess.Count != 0)
  235. //{
  236. // string messageToProcess = "<root>" + MessagesToProcess.First() + "</root>";
  237. // MessagesToProcess.Remove(MessagesToProcess.First());
  238. // XDocument xdoc = XDocument.Parse(messageToProcess);
  239. // XElement root = new List<XElement>(xdoc.Descendants(XName.Get("root")))[0];
  240. // foreach (XElement elem in root.Elements())
  241. // {
  242. // string xmlData = elem.ToString();
  243. // MemoryStream xmlStream = new MemoryStream(UTF8Encoding.UTF8.GetBytes(xmlData));
  244. // DataContractSerializer dcs = new DataContractSerializer(typeof(object), KnownTypes.Get());
  245. // object data = dcs.ReadObject(xmlStream);
  246. // ProcessMessage(data);
  247. // }
  248. //}
  249. }
  250. catch (Exception ex)
  251. {
  252. throw ex;
  253. }
  254. finally
  255. {
  256. ReceiveThreadBusy = false;
  257. }
  258. //uiThread.Post(delegate(object obj)
  259. //{
  260. // Commons.Storage.Log((string)obj);
  261. //}, "Exit OnReceive in lock");
  262. }
  263. //uiThread.Post(delegate(object obj)
  264. //{
  265. // Commons.Storage.Log((string)obj);
  266. //}, "Exit OnReceive out lock");
  267. Socket s = e.UserToken as Socket;
  268. byte[] response = new byte[ResponseBufferSize];
  269. e.SetBuffer(response, 0, response.Length);
  270. s.ReceiveAsync(e);
  271. }
  272. #endregion
  273. #region "Error processing"
  274. private void ProcessError(SocketAsyncEventArgs e)
  275. {
  276. Socket s = e.UserToken as Socket;
  277. if (s.Connected)
  278. {
  279. try
  280. {
  281. s.Shutdown(SocketShutdown.Both);
  282. }
  283. catch (Exception)
  284. {
  285. }
  286. finally
  287. {
  288. if (s.Connected)
  289. s.Close();
  290. }
  291. }
  292. //throw new SocketException((int)e.SocketError);
  293. }
  294. #endregion
  295. public override void Disconnect()
  296. {
  297. Initialized = false;
  298. socket.Shutdown(SocketShutdown.Both);
  299. if (socket.Connected)
  300. socket.Close();
  301. }
  302. }
  303. }