Session.SilverlightShared.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. using System;
  2. using System.Linq;
  3. using System.Net;
  4. using System.Net.Sockets;
  5. using System.Threading;
  6. using Renci.SshNet.Common;
  7. using Renci.SshNet.Messages.Transport;
  8. using System.Text;
  9. using Renci.SshNet.Messages;
  10. namespace Renci.SshNet
  11. {
  12. public partial class Session
  13. {
  14. private readonly AutoResetEvent _autoEvent = new AutoResetEvent(false);
  15. private readonly AutoResetEvent _sendEvent = new AutoResetEvent(false);
  16. private readonly AutoResetEvent _receiveEvent = new AutoResetEvent(false);
  17. private bool _isConnected = false;
  18. partial void IsSocketConnected(ref bool isConnected)
  19. {
  20. isConnected = (!this._isDisconnecting && this._socket != null && this._socket.Connected && this._isAuthenticated && this._messageListenerCompleted != null && this._isConnected);
  21. }
  22. partial void SocketConnect(string host, int port)
  23. {
  24. var ep = new DnsEndPoint(host, port);
  25. this._socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  26. var args = new SocketAsyncEventArgs();
  27. args.UserToken = this._socket;
  28. args.RemoteEndPoint = ep;
  29. args.Completed += new EventHandler<SocketAsyncEventArgs>(OnConnect);
  30. this._socket.ConnectAsync(args);
  31. this._autoEvent.WaitOne(this.ConnectionInfo.Timeout);
  32. if (args.SocketError != SocketError.Success)
  33. throw new SocketException((int)args.SocketError);
  34. }
  35. partial void SocketDisconnect()
  36. {
  37. this._socket.Close(10000);
  38. }
  39. partial void SocketReadLine(ref string response)
  40. {
  41. // TODO: Improve this function, currently will not work with server that send multiple lines as a first string
  42. var buffer = new byte[1024];
  43. StringBuilder result = new StringBuilder();
  44. do
  45. {
  46. SocketAsyncEventArgs args = new SocketAsyncEventArgs();
  47. args.SetBuffer(buffer, 0, buffer.Length);
  48. args.UserToken = this._socket;
  49. args.RemoteEndPoint = this._socket.RemoteEndPoint;
  50. args.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
  51. this._socket.ReceiveAsync(args);
  52. this._receiveEvent.WaitOne(this.ConnectionInfo.Timeout);
  53. char lastChar = (char)buffer[0];
  54. for (int i = 1; i < args.BytesTransferred; i++)
  55. {
  56. char newChar = (char)buffer[i];
  57. if (lastChar == '\r' && newChar == '\n')
  58. break;
  59. result.Append(lastChar);
  60. lastChar = newChar;
  61. }
  62. if (args.BytesTransferred < buffer.Length)
  63. break;
  64. } while (true);
  65. response = result.ToString();
  66. }
  67. partial void SocketRead(int length, ref byte[] buffer)
  68. {
  69. var offset = 0;
  70. int receivedTotal = 0; // how many bytes is already received
  71. do
  72. {
  73. SocketAsyncEventArgs args = new SocketAsyncEventArgs();
  74. args.SetBuffer(buffer, offset + receivedTotal, length - receivedTotal);
  75. args.UserToken = this._socket;
  76. args.RemoteEndPoint = this._socket.RemoteEndPoint;
  77. args.Completed += new EventHandler<SocketAsyncEventArgs>(OnReceive);
  78. this._socket.ReceiveAsync(args);
  79. this._receiveEvent.WaitOne(this.ConnectionInfo.Timeout);
  80. if (args.SocketError == SocketError.WouldBlock ||
  81. args.SocketError == SocketError.IOPending ||
  82. args.SocketError == SocketError.NoBufferSpaceAvailable)
  83. {
  84. // socket buffer is probably empty, wait and try again
  85. Thread.Sleep(30);
  86. continue;
  87. }
  88. else if (args.SocketError != SocketError.Success)
  89. {
  90. throw new SocketException((int)args.SocketError);
  91. }
  92. var receivedBytes = args.BytesTransferred;
  93. if (receivedBytes > 0)
  94. {
  95. receivedTotal += receivedBytes;
  96. continue;
  97. }
  98. else
  99. {
  100. throw new SshConnectionException("An established connection was aborted by the software in your host machine.", DisconnectReason.ConnectionLost);
  101. }
  102. } while (receivedTotal < length);
  103. }
  104. partial void SocketWrite(byte[] data)
  105. {
  106. if (this._isConnected)
  107. {
  108. SocketAsyncEventArgs args = new SocketAsyncEventArgs();
  109. args.SetBuffer(data, 0, data.Length);
  110. args.UserToken = this._socket;
  111. args.RemoteEndPoint = this._socket.RemoteEndPoint;
  112. args.Completed += new EventHandler<SocketAsyncEventArgs>(OnSend);
  113. this._socket.SendAsync(args);
  114. }
  115. else
  116. throw new SocketException((int)SocketError.NotConnected);
  117. }
  118. private void OnConnect(object sender, SocketAsyncEventArgs e)
  119. {
  120. this._autoEvent.Set();
  121. this._isConnected = (e.SocketError == SocketError.Success);
  122. }
  123. private void OnSend(object sender, SocketAsyncEventArgs e)
  124. {
  125. this._sendEvent.Set();
  126. }
  127. private void OnReceive(object sender, SocketAsyncEventArgs e)
  128. {
  129. this._receiveEvent.Set();
  130. }
  131. partial void ExecuteThread(Action action)
  132. {
  133. ThreadPool.QueueUserWorkItem((o) => { action(); });
  134. }
  135. partial void InternalRegisterMessage(string messageName)
  136. {
  137. lock (this._messagesMetadata)
  138. {
  139. foreach (var item in from m in this._messagesMetadata where m.Name == messageName select m)
  140. {
  141. item.Enabled = true;
  142. item.Activated = true;
  143. }
  144. }
  145. }
  146. partial void InternalUnRegisterMessage(string messageName)
  147. {
  148. lock (this._messagesMetadata)
  149. {
  150. foreach (var item in from m in this._messagesMetadata where m.Name == messageName select m)
  151. {
  152. item.Enabled = false;
  153. item.Activated = false;
  154. }
  155. }
  156. }
  157. }
  158. }