SocketWithTimeout.cs
上传用户:szltgg
上传日期:2019-05-16
资源大小:604k
文件大小:6k
源码类别:

Telnet服务器

开发平台:

C#

  1. /*
  2. * Copyright (c) 2005 Poderosa Project, All Rights Reserved.
  3. * $Id: SocketWithTimeout.cs,v 1.2 2005/04/20 08:45:46 okajima Exp $
  4. */
  5. using System;
  6. using System.Collections.Specialized;
  7. using System.Diagnostics;
  8. using System.Threading;
  9. using System.Net;
  10. using System.Net.Sockets;
  11. namespace Poderosa.Communication
  12. {
  13. public interface ISocketWithTimeoutClient {
  14. void SuccessfullyExit(object result);
  15. void ConnectionFailed(string message);
  16. void CancelTimer();
  17. System.Windows.Forms.IWin32Window GetWindow();
  18. }
  19. /// <summary>
  20. /// 僜働僢僩傪奐偒丄愙懕傪妋棫偡傞庤弴傪偟偮偮僞僀儉傾僂僩傗搑拞偱拞巭偡傞偙偲傕偱偒傞偨傔偺婡擻
  21. /// </summary>
  22. public abstract class SocketWithTimeout {
  23. public void AsyncConnect(ISocketWithTimeoutClient client, string host, int port) {
  24. _async = true;
  25. _client = client;
  26. _event = null;
  27. _host = host;
  28. _port = port;
  29. _socks = null;
  30. UI.UILibUtil.CreateThread(new ThreadStart(this.Run)).Start();
  31. }
  32. public void AsyncConnect(ISocketWithTimeoutClient client, Socks socks) {
  33. _async = true;
  34. _client = client;
  35. _event = null;
  36. _socks = socks;
  37. UI.UILibUtil.CreateThread(new ThreadStart(this.Run)).Start();
  38. }
  39. private void ExitProcess() {
  40. if(!_interrupted) {
  41. if(_succeeded)
  42. _client.SuccessfullyExit(this.Result);
  43. else
  44. _client.ConnectionFailed(_errorMessage);
  45. }
  46. }
  47. protected void SetIgnoreTimeout() {
  48. _ignoreTimeout = true;
  49. _client.CancelTimer();
  50. }
  51. public void Interrupt() {
  52. _interrupted = true;
  53. if(!_async)
  54. _event.Set();
  55. if(_tcpConnected)
  56. _socket.Close();
  57. }
  58. protected Socks _socks;
  59. protected ISocketWithTimeoutClient _client;
  60. protected IPAddressSet _addressSet;
  61. protected IPAddress _connectedAddress;
  62. protected AutoResetEvent _event;
  63. protected Socket _socket;
  64. protected string _host;
  65. protected int _port;
  66. protected bool _async;
  67. protected bool _succeeded;
  68. protected bool _interrupted;
  69. protected bool _ignoreTimeout;
  70. protected bool _tcpConnected;
  71. protected string _errorMessage;
  72. private void Run() {
  73. _tcpConnected = false;
  74. _ignoreTimeout = false;
  75. _succeeded = false;
  76. try {
  77. _addressSet = null;
  78. _errorMessage = null;
  79. MakeConnection();
  80. _errorMessage = null;
  81. Negotiate();
  82. _succeeded = true;
  83. }
  84. catch(Exception ex) {
  85. if(_errorMessage==null)
  86. _errorMessage = ex.Message;
  87. else
  88. _errorMessage += ex.Message;
  89. }
  90. finally {
  91. if(_async) {
  92. ExitProcess();
  93. }
  94. else {
  95. _event.Set();
  96. _event.Close();
  97. }
  98. if(_tcpConnected && !_interrupted && _errorMessage!=null) {
  99. try {
  100. _socket.Close();
  101. }
  102. catch(Exception) { //偙偙偱偪傖傫偲暵偠傞偙偲偑弌棃側偄応崌偑偁偭偨
  103. }
  104. }
  105. }
  106. }
  107. protected virtual void MakeConnection() {
  108. //傑偢SOCKS傪巊偆傋偒偐偳偆偐傪敾掕偡傞
  109. if(_socks!=null) {
  110. IPAddressSet a = null;
  111. try {
  112. a = new IPAddressSet(IPAddress.Parse(_socks.DestName));
  113. }
  114. catch(FormatException ) {
  115. try {
  116. a = new IPAddressSet(_socks.DestName);
  117. }
  118. catch(Exception) { //偙偙偱柤慜夝寛偱偒偢偲傕丄SOCKS僒乕僶偑夝寛偱偒傞偐傕偟傟側偄偺偱僄儔乕偵偼偟側偄
  119. }
  120. }
  121. if(a!=null && !SocksApplicapable(_socks.ExcludingNetworks, a)) { //SOCKS傪巊傢側偄偙偲偑妋掕
  122. _addressSet = a;
  123. _host = _socks.DestName;
  124. _port = _socks.DestPort;
  125. _socks = null;
  126. }
  127. }
  128. string dest = _socks==null? _host : _socks.ServerName;
  129. int    port = _socks==null? _port : _socks.ServerPort;
  130. string msg  = _socks==null? GetHostDescription() : "SOCKS Server";
  131. if(_addressSet==null) {
  132. try {
  133. _addressSet = new IPAddressSet(IPAddress.Parse(dest)); //嵟弶偐傜IP傾僪儗僗宍幃偺偲偒偼庤偱曄姺丅偦偆偱側偄偲DNS偺媡堷偒傪偟偰僞僀儉傾僂僩丄偲偐傗傗偙偟偄偙偲偑婲偙傞
  134. }
  135. catch(FormatException ) {
  136. _errorMessage = String.Format("The {0} {1} was not found.", msg, dest);
  137. _addressSet = new IPAddressSet(dest);
  138. }
  139. }
  140. _errorMessage = String.Format("Failed to connect {0} {1}. Please check the address and the port.", msg, dest);
  141. _socket = NetUtil.ConnectTCPSocket(_addressSet, port);
  142. _connectedAddress = ((IPEndPoint)_socket.RemoteEndPoint).Address;
  143. if(_socks!=null) {
  144. _errorMessage = "An error occurred while SOCKS negotiation.";
  145. _socks.Connect(_socket);
  146. _host = _socks.DestName;
  147. _port = _socks.DestPort;
  148. }
  149. _tcpConnected = true;
  150. }
  151. //偙傟傪僆乕僶乕儔僀僪偟偰TCP愙懕屻偺摦嶌傪偡傞
  152. protected abstract void Negotiate();
  153. protected virtual string GetHostDescription() {
  154. return "";
  155. }
  156. //惉岟偟偨傜偙傟傪幚憰偟偰寢壥傪曉偡
  157. protected abstract object Result {
  158. get;
  159. }
  160. public Socks Socks {
  161. get {
  162. return _socks;
  163. }
  164. set {
  165. _socks = value;
  166. }
  167. }
  168. public bool Succeeded {
  169. get {
  170. return _succeeded;
  171. }
  172. }
  173. public bool Interrupted {
  174. get {
  175. return _interrupted;
  176. }
  177. }
  178. public string ErrorMessage {
  179. get {
  180. return _errorMessage;
  181. }
  182. }
  183. public IPAddress IPAddress {
  184. get {
  185. return _connectedAddress;
  186. }
  187. }
  188. private static bool SocksApplicapable(string nss, IPAddressSet address) {
  189. foreach(string netaddress in nss.Split(';')) {
  190. if(netaddress.Length==0) continue;
  191. if(!NetUtil.IsNetworkAddress(netaddress)) {
  192. throw new FormatException(String.Format("{0} is not suitable as a network address.", netaddress));
  193. }
  194. if(NetUtil.NetAddressIncludesIPAddress(netaddress, address.Primary))
  195. return false;
  196. else if(address.Secondary!=null && NetUtil.NetAddressIncludesIPAddress(netaddress, address.Secondary))
  197. return false;
  198. }
  199. return true;
  200. }
  201. }
  202. }