TcpServerChannel.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. //
  2. // System.Runtime.Remoting.Channels.Tcp.TcpChannel.cs
  3. //
  4. // Author: Rodrigo Moya ([email protected])
  5. //
  6. // 2002 (C) Copyright, Ximian, Inc.
  7. //
  8. using System.Collections;
  9. using System.Runtime.Remoting.Messaging;
  10. using System.Text.RegularExpressions;
  11. using System.Net.Sockets;
  12. using System.Net;
  13. using System.Threading;
  14. using System.IO;
  15. namespace System.Runtime.Remoting.Channels.Tcp
  16. {
  17. public class TcpServerTransportSink : IServerChannelSink, IChannelSinkBase
  18. {
  19. IServerChannelSink next_sink;
  20. public TcpServerTransportSink (IServerChannelSink next)
  21. {
  22. next_sink = next;
  23. }
  24. public IServerChannelSink NextChannelSink {
  25. get {
  26. return next_sink;
  27. }
  28. }
  29. [MonoTODO]
  30. public IDictionary Properties {
  31. get {
  32. throw new NotImplementedException ();
  33. }
  34. }
  35. [MonoTODO]
  36. public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,
  37. IMessage msg, ITransportHeaders headers, Stream stream)
  38. {
  39. throw new NotImplementedException ();
  40. }
  41. [MonoTODO]
  42. public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,
  43. IMessage msg, ITransportHeaders headers)
  44. {
  45. throw new NotImplementedException ();
  46. }
  47. public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,
  48. IMessage requestMsg,
  49. ITransportHeaders requestHeaders,
  50. Stream requestStream,
  51. out IMessage responseMsg,
  52. out ITransportHeaders responseHeaders,
  53. out Stream responseStream)
  54. {
  55. // this is the first sink, and TcpServerChannel does not call it.
  56. throw new NotSupportedException ();
  57. }
  58. internal void InternalProcessMessage (Stream requestStream)
  59. {
  60. Console.WriteLine ("ProcessMessageInternal");
  61. }
  62. }
  63. public class TcpServerChannel : IChannelReceiver, IChannel
  64. {
  65. int port = 0;
  66. string name = "tcp";
  67. string host;
  68. int priority = 1;
  69. Thread server_thread = null;
  70. TcpListener listener;
  71. TcpServerTransportSink sink;
  72. ChannelDataStore channel_data;
  73. void Init (IServerChannelSinkProvider provider) {
  74. if (provider == null) {
  75. provider = new BinaryServerFormatterSinkProvider ();
  76. }
  77. IServerChannelSink next_sink = provider.CreateSink (this);
  78. host = Dns.GetHostByName(Dns.GetHostName()).HostName;
  79. string [] uris = null;
  80. if (port != 0) {
  81. uris = new String [1];
  82. uris [0] = GetChannelUri ();
  83. }
  84. channel_data = new ChannelDataStore (uris);;
  85. sink = new TcpServerTransportSink (next_sink);
  86. listener = new TcpListener (port);
  87. StartListening (null);
  88. }
  89. public TcpServerChannel (int port)
  90. {
  91. this.port = port;
  92. Init (null);
  93. }
  94. public TcpServerChannel (IDictionary properties,
  95. IServerChannelSinkProvider serverSinkProvider)
  96. {
  97. port = (int)properties ["port"];
  98. Init (serverSinkProvider);
  99. }
  100. public TcpServerChannel (string name, int port,
  101. IServerChannelSinkProvider serverSinkProvider)
  102. {
  103. name = name;
  104. this.port = port;
  105. Init (serverSinkProvider);
  106. }
  107. public TcpServerChannel (string name, int port)
  108. {
  109. name = name;
  110. this.port = port;
  111. Init (null);
  112. }
  113. public object ChannelData
  114. {
  115. get {
  116. return channel_data;
  117. }
  118. }
  119. public string ChannelName
  120. {
  121. get {
  122. return name;
  123. }
  124. }
  125. public int ChannelPriority
  126. {
  127. get {
  128. return priority;
  129. }
  130. }
  131. public string GetChannelUri ()
  132. {
  133. return "tcp://" + host + ":" + port;
  134. }
  135. public string[] GetUrlsForUri (string uri)
  136. {
  137. string [] result = new String [1];
  138. if (uri.IndexOf ('/') != 0)
  139. result [0] = GetChannelUri () + "/" + uri;
  140. else
  141. result [0] = GetChannelUri () + uri;
  142. return result;
  143. }
  144. public string Parse (string url, out string objectURI)
  145. {
  146. int port;
  147. string host = TcpChannel.ParseTcpURL (url, out objectURI, out port);
  148. return "tcp://" + host + ":" + port;
  149. }
  150. void WaitForConnections ()
  151. {
  152. while (true) {
  153. TcpClient client = listener.AcceptTcpClient ();
  154. sink.InternalProcessMessage (client.GetStream ());
  155. client.Close ();
  156. }
  157. }
  158. public void StartListening (object data)
  159. {
  160. if (server_thread == null) {
  161. listener.Start ();
  162. if (port == 0) {
  163. port = ((IPEndPoint)listener.LocalEndpoint).Port;
  164. channel_data.ChannelUris = new String [1];
  165. channel_data.ChannelUris [0] = GetChannelUri ();
  166. }
  167. server_thread = new Thread (new ThreadStart (WaitForConnections));
  168. server_thread.Start ();
  169. }
  170. }
  171. public void StopListening (object data)
  172. {
  173. if (server_thread != null) {
  174. server_thread.Abort ();
  175. server_thread = null;
  176. listener.Stop ();
  177. }
  178. }
  179. }
  180. }