TcpDuplexSessionChannel.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. //
  2. // TcpDuplexSessionChannel.cs
  3. //
  4. // Author:
  5. // Marcos Cobena ([email protected])
  6. //
  7. // Copyright 2007 Marcos Cobena (http://www.youcannoteatbits.org/)
  8. //
  9. using System;
  10. using System.IO;
  11. using System.Net;
  12. using System.Net.Sockets;
  13. using System.Runtime.Serialization;
  14. using System.Runtime.Serialization.Formatters.Binary;
  15. using System.ServiceModel.Channels;
  16. using System.Xml;
  17. namespace System.ServiceModel.Channels
  18. {
  19. internal class TcpDuplexSessionChannel : DuplexChannelBase, IDuplexSessionChannel
  20. {
  21. TcpChannelInfo info;
  22. TcpClient client;
  23. bool is_service_side;
  24. EndpointAddress local_address;
  25. EndpointAddress remote_address;
  26. TcpListener tcp_listener;
  27. TimeSpan timeout;
  28. Uri via;
  29. public TcpDuplexSessionChannel (ChannelFactoryBase factory, TcpChannelInfo info, EndpointAddress address, Uri via)
  30. : base (factory)
  31. {
  32. is_service_side = false;
  33. this.info = info;
  34. remote_address = address;
  35. this.via = via;
  36. }
  37. public TcpDuplexSessionChannel (ChannelListenerBase listener, TcpChannelInfo info, TcpClient acceptedRequest, TimeSpan timeout)
  38. : base (listener)
  39. {
  40. is_service_side = true;
  41. this.info = info;
  42. this.client = acceptedRequest;
  43. this.timeout = timeout;
  44. Stream s = client.GetStream ();
  45. //while (s.CanRead)
  46. // Console.Write ("{0:X02} ", s.ReadByte ());
  47. for (int i = 0; i < 6; i++)
  48. s.ReadByte ();
  49. int size = s.ReadByte ();
  50. for (int i = 0; i < size; i++)
  51. s.ReadByte (); // URI
  52. s.ReadByte ();
  53. s.ReadByte ();
  54. s.ReadByte ();
  55. s.WriteByte (0x0B);
  56. }
  57. public MessageEncoder Encoder {
  58. get { return info.MessageEncoder; }
  59. }
  60. public override EndpointAddress LocalAddress {
  61. get { return local_address; }
  62. }
  63. public override EndpointAddress RemoteAddress {
  64. get { return remote_address; }
  65. }
  66. // FIXME: implement
  67. public IDuplexSession Session {
  68. get { throw new NotImplementedException (); }
  69. }
  70. public override Uri Via {
  71. get { return via; }
  72. }
  73. [MonoTODO]
  74. public override IAsyncResult BeginSend (Message message, AsyncCallback callback, object state)
  75. {
  76. throw new NotImplementedException ();
  77. }
  78. [MonoTODO]
  79. public override IAsyncResult BeginSend (Message message, TimeSpan timeout, AsyncCallback callback, object state)
  80. {
  81. throw new NotImplementedException ();
  82. }
  83. [MonoTODO]
  84. public override void EndSend (IAsyncResult result)
  85. {
  86. throw new NotImplementedException ();
  87. }
  88. [MonoTODO]
  89. public override void Send (Message message)
  90. {
  91. MemoryStream ms = new MemoryStream ();
  92. BinaryFormatter bf = new BinaryFormatter ();
  93. try
  94. {
  95. NetworkStream stream = client.GetStream ();
  96. MyBinaryWriter bw = new MyBinaryWriter (stream);
  97. bw.Write ((byte) 6);
  98. Encoder.WriteMessage (message, ms);
  99. bw.WriteBytes (ms.ToArray ());
  100. bw.Write ((byte) 7);
  101. bw.Flush ();
  102. stream.ReadByte (); // 7
  103. }
  104. catch (Exception e)
  105. {
  106. throw e;
  107. }
  108. }
  109. [MonoTODO]
  110. public override void Send (Message message, TimeSpan timeout)
  111. {
  112. throw new NotImplementedException ();
  113. }
  114. [MonoTODO]
  115. public override IAsyncResult BeginReceive (AsyncCallback callback, object state)
  116. {
  117. throw new NotImplementedException ();
  118. }
  119. [MonoTODO]
  120. public override IAsyncResult BeginReceive (TimeSpan timeout, AsyncCallback callback, object state)
  121. {
  122. throw new NotImplementedException ();
  123. }
  124. [MonoTODO]
  125. public override IAsyncResult BeginTryReceive (TimeSpan timeout, AsyncCallback callback, object state)
  126. {
  127. throw new NotImplementedException ();
  128. }
  129. [MonoTODO]
  130. public override IAsyncResult BeginWaitForMessage (TimeSpan timeout, AsyncCallback callback, object state)
  131. {
  132. throw new NotImplementedException ();
  133. }
  134. [MonoTODO]
  135. public override Message EndReceive (IAsyncResult result)
  136. {
  137. throw new NotImplementedException ();
  138. }
  139. [MonoTODO]
  140. public override bool EndTryReceive (IAsyncResult result, out Message message)
  141. {
  142. throw new NotImplementedException ();
  143. }
  144. [MonoTODO]
  145. public override bool EndWaitForMessage (IAsyncResult result)
  146. {
  147. throw new NotImplementedException ();
  148. }
  149. [MonoTODO]
  150. public override Message Receive ()
  151. {
  152. Stream s = client.GetStream ();
  153. s.ReadByte (); // 6
  154. MyBinaryReader br = new MyBinaryReader (s);
  155. // string msg = br.ReadString ();
  156. // br.Read7BitEncodedInt ();
  157. byte [] buffer = new byte [65536];
  158. buffer = br.ReadBytes ();
  159. MemoryStream ms = new MemoryStream ();
  160. ms.Write (buffer, 0, buffer.Length);
  161. ms.Seek (0, SeekOrigin.Begin);
  162. // while (s.CanRead)
  163. // Console.Write ("{0:X02} ", s.ReadByte ());
  164. Message msg = null;
  165. // FIXME: To supply maxSizeOfHeaders.
  166. msg = Encoder.ReadMessage (ms, 0x10000);
  167. s.ReadByte (); // 7
  168. // Console.WriteLine (msg);
  169. s.WriteByte (7);
  170. s.Flush ();
  171. return msg;
  172. }
  173. [MonoTODO]
  174. public override Message Receive (TimeSpan timeout)
  175. {
  176. throw new NotImplementedException ();
  177. }
  178. [MonoTODO]
  179. public override bool TryReceive (TimeSpan timeout, out Message message)
  180. {
  181. throw new NotImplementedException ();
  182. }
  183. [MonoTODO]
  184. public override bool WaitForMessage (TimeSpan timeout)
  185. {
  186. throw new NotImplementedException ();
  187. }
  188. // CommunicationObject
  189. [MonoTODO]
  190. protected override void OnAbort ()
  191. {
  192. throw new NotImplementedException ();
  193. }
  194. [MonoTODO]
  195. protected override IAsyncResult OnBeginClose (TimeSpan timeout,
  196. AsyncCallback callback, object state)
  197. {
  198. throw new NotImplementedException ();
  199. }
  200. [MonoTODO]
  201. protected override IAsyncResult OnBeginOpen (TimeSpan timeout,
  202. AsyncCallback callback, object state)
  203. {
  204. throw new NotImplementedException ();
  205. }
  206. [MonoTODO]
  207. protected override void OnClose (TimeSpan timeout)
  208. {
  209. client.Close ();
  210. }
  211. [MonoTODO]
  212. protected override void OnEndClose (IAsyncResult result)
  213. {
  214. throw new NotImplementedException ();
  215. }
  216. [MonoTODO]
  217. protected override void OnEndOpen (IAsyncResult result)
  218. {
  219. throw new NotImplementedException ();
  220. }
  221. [MonoTODO]
  222. protected override void OnOpen (TimeSpan timeout)
  223. {
  224. if (! is_service_side) {
  225. int explicitPort = RemoteAddress.Uri.Port;
  226. client = new TcpClient (RemoteAddress.Uri.Host, explicitPort <= 0 ? TcpTransportBindingElement.DefaultPort : explicitPort);
  227. //RemoteAddress.Uri.Port);
  228. NetworkStream ns = client.GetStream ();
  229. ns.WriteByte (0);
  230. ns.WriteByte (1);
  231. ns.WriteByte (0);
  232. ns.WriteByte (1);
  233. ns.WriteByte (2);
  234. ns.WriteByte (2);
  235. byte [] bytes = System.Text.Encoding.UTF8.GetBytes (RemoteAddress.Uri.ToString ());
  236. ns.WriteByte ((byte) bytes.Length);
  237. ns.Write (bytes, 0, bytes.Length);
  238. ns.WriteByte (3);
  239. ns.WriteByte (3);
  240. ns.WriteByte (0xC);
  241. int hoge = ns.ReadByte ();
  242. //while (ns.CanRead)
  243. // Console.Write ("{0:X02} ", ns.ReadByte ());
  244. }
  245. // Service side.
  246. /*
  247. else
  248. Console.WriteLine ("Server side.");
  249. */
  250. }
  251. // FIXME: To look for other way to do this.
  252. class MyBinaryReader : BinaryReader
  253. {
  254. public MyBinaryReader (Stream s)
  255. : base (s)
  256. {
  257. }
  258. public byte [] ReadBytes ()
  259. {
  260. byte [] buffer = new byte [65536];
  261. int length = Read7BitEncodedInt ();
  262. if (length > 65536)
  263. throw new InvalidOperationException ("The message is too large.");
  264. Read (buffer, 0, length);
  265. return buffer;
  266. }
  267. }
  268. class MyBinaryWriter : BinaryWriter
  269. {
  270. public MyBinaryWriter (Stream s)
  271. : base (s)
  272. {
  273. }
  274. public void WriteBytes (byte [] bytes)
  275. {
  276. Write7BitEncodedInt (bytes.Length);
  277. Write (bytes);
  278. }
  279. }
  280. }
  281. }