TcpClientSocket.cs (8817B)
1 using System; 2 using System.Runtime.InteropServices.WindowsRuntime; 3 using System.Threading; 4 using System.Threading.Tasks; 5 using System.Windows; 6 using System.Windows.Threading; 7 using Windows.Networking.Sockets; 8 using Windows.Storage.Streams; 9 10 namespace WinPhoneFtp.FtpService 11 { 12 public sealed class TcpClientSocket : IDisposable 13 { 14 String IpAddress = String.Empty; 15 String Port = String.Empty; 16 StreamSocket streamSocket = null; 17 String SocketName = String.Empty; 18 DataWriter TcpStreamWriter = null; 19 Boolean IsConnectionClosedByRemoteHost = false; 20 UInt32 ReadBufferLength = 0; 21 Boolean IsSocketConnected = false; 22 Logger logger = null; 23 Dispatcher UIDispatcher = null; 24 DataReader TcpStreamReader = null; 25 26 public event EventHandler<DataReceivedEventArgs> DataReceived; 27 public event EventHandler<SocketClosedEventArgs> SocketClosed; 28 public event EventHandler<ErrorOccuredEventArgs> ErrorOccured; 29 public event EventHandler SocketConnected; 30 31 public TcpClientSocket(String IpAddress, String Port, Dispatcher UIDispatcher) 32 : this(IpAddress, Port, 512, "NoName", UIDispatcher) 33 { 34 } 35 36 public TcpClientSocket(String IpAddress, String Port, UInt32 ReadBufferLength, Dispatcher UIDispatcher) 37 : this(IpAddress, Port, ReadBufferLength, "NoName", UIDispatcher) 38 { 39 } 40 41 public TcpClientSocket(String IpAddress, String Port, String SocketName, Dispatcher UIDispatcher) 42 : this(IpAddress, Port, 512, SocketName, UIDispatcher) 43 { 44 } 45 46 public TcpClientSocket(String IpAddress, String Port, UInt32 ReadBufferLength, String SocketName, Dispatcher UIDispatcher) 47 { 48 this.UIDispatcher = UIDispatcher != null ? UIDispatcher : Deployment.Current.Dispatcher; 49 logger = Logger.GetDefault(UIDispatcher); 50 this.IpAddress = IpAddress; 51 this.Port = Port; 52 this.SocketName = SocketName; 53 this.ReadBufferLength = ReadBufferLength; 54 //logger.AddLog(String.Format("Creating new TCP Socket {0}. IPAddress: {1}, Port: {2}", SocketName, IpAddress, Port)); 55 } 56 57 public async Task PrepareSocketAsync() 58 { 59 streamSocket = new StreamSocket(); 60 61 //logger.AddLog(String.Format("Connecting {0} socket at IPAddress: {1}, Port: {2}", SocketName, IpAddress, Port)); 62 try 63 { 64 await streamSocket.ConnectAsync(new Windows.Networking.HostName(IpAddress), Port); 65 } 66 catch (Exception ex) 67 { 68 //logger.AddLog("Unable to connect to remote connection"); 69 RaiseErrorOccuredEvent(ex); 70 return; 71 } 72 //logger.AddLog("Connected"); 73 TcpStreamWriter = new DataWriter(streamSocket.OutputStream); 74 IsSocketConnected = true; 75 try 76 { 77 await Task.Factory.StartNew(stream => 78 { 79 TcpStreamReader = new DataReader((IInputStream)stream); 80 TcpStreamReader.InputStreamOptions = InputStreamOptions.Partial; 81 try 82 { 83 DataReaderLoadOperation loadOperation = TcpStreamReader.LoadAsync(ReadBufferLength); 84 loadOperation.Completed = new Windows.Foundation.AsyncOperationCompletedHandler<UInt32>(LoadCompleted); 85 } 86 catch (Exception ex) 87 { 88 RaiseErrorOccuredEvent(ex); 89 } 90 }, streamSocket.InputStream); 91 } 92 catch 93 { 94 //logger.AddLog("Asynchronous Read Operation Canceled"); 95 } 96 RaiseSocketConnectedEvent(); 97 } 98 99 private void LoadCompleted(Windows.Foundation.IAsyncOperation<uint> asyncInfo, Windows.Foundation.AsyncStatus asyncStatus) 100 { 101 switch (asyncStatus) 102 { 103 case Windows.Foundation.AsyncStatus.Canceled: 104 //logger.AddLog("Data load operation canceled"); 105 break; 106 107 case Windows.Foundation.AsyncStatus.Completed: 108 //logger.AddLog("Data load operation completed"); 109 if (TcpStreamReader.UnconsumedBufferLength.Equals(0)) 110 { 111 if (IsSocketConnected) 112 { 113 //logger.AddLog("Connection closed by remote host. Exiting"); 114 IsSocketConnected = false; 115 IsConnectionClosedByRemoteHost = true; 116 CloseSocket(); 117 } 118 } 119 else 120 { 121 IBuffer buffer = TcpStreamReader.DetachBuffer(); 122 RaiseDataReceivedEvent(buffer.ToArray()); 123 DataReaderLoadOperation loadOperation = TcpStreamReader.LoadAsync(ReadBufferLength); 124 loadOperation.Completed = new Windows.Foundation.AsyncOperationCompletedHandler<UInt32>(LoadCompleted); 125 } 126 break; 127 128 case Windows.Foundation.AsyncStatus.Error: 129 //logger.AddLog("Exception in data load operation"); 130 IsSocketConnected = false; 131 if (asyncInfo.ErrorCode.HResult.Equals(-2147014842)) 132 { 133 IsConnectionClosedByRemoteHost = true; 134 } 135 else 136 { 137 RaiseErrorOccuredEvent(asyncInfo.ErrorCode); 138 } 139 CloseSocket(); 140 break; 141 142 case Windows.Foundation.AsyncStatus.Started: 143 //logger.AddLog("Data load operation started"); 144 break; 145 } 146 } 147 148 public async Task SendDataAsync(byte[] data) 149 { 150 if (TcpStreamWriter != null) 151 { 152 TcpStreamWriter.WriteBytes(data); 153 await TcpStreamWriter.StoreAsync(); 154 } 155 } 156 157 public async Task SendDataAsync(String data) 158 { 159 if (TcpStreamWriter != null) 160 { 161 TcpStreamWriter.WriteString(data); 162 await TcpStreamWriter.StoreAsync(); 163 } 164 } 165 166 [System.Security.SecuritySafeCritical()] 167 public void CloseSocket() 168 { 169 IsSocketConnected = false; 170 //logger.AddLog(String.Format("Closing {0} socket", SocketName)); 171 if (TcpStreamWriter != null) 172 { 173 //loadOperation.Close(); 174 TcpStreamWriter.Dispose(); 175 TcpStreamWriter = null; 176 } 177 178 if (streamSocket != null) 179 { 180 DataReceived = null; 181 ErrorOccured = null; 182 if (!IsConnectionClosedByRemoteHost) 183 { 184 //loadOperation.Cancel(); 185 RaiseSocketClosedEvent(SocketCloseReason.ClosedFromLocalHost); 186 } 187 else 188 { 189 RaiseSocketClosedEvent(SocketCloseReason.ClosedByRemoteHost); 190 } 191 SocketClosed = null; 192 streamSocket.Dispose(); 193 streamSocket = null; 194 } 195 } 196 197 private void RaiseDataReceivedEvent(Byte[] data) 198 { 199 if (DataReceived != null) 200 { 201 DataReceived(this, new DataReceivedEventArgs(data)); 202 } 203 } 204 205 private void RaiseSocketClosedEvent(SocketCloseReason CloseReason) 206 { 207 if (SocketClosed != null) 208 { 209 SocketClosed(this, new SocketClosedEventArgs(CloseReason)); 210 } 211 } 212 213 private void RaiseErrorOccuredEvent(Exception ExceptionObject) 214 { 215 if (ErrorOccured != null) 216 { 217 ErrorOccured(this, new ErrorOccuredEventArgs(ExceptionObject)); 218 } 219 } 220 221 private void RaiseSocketConnectedEvent() 222 { 223 if (SocketConnected != null) 224 { 225 SocketConnected(this, EventArgs.Empty); 226 } 227 } 228 229 public async void Dispose() 230 { 231 if (TcpStreamWriter != null) 232 { 233 await TcpStreamWriter.FlushAsync(); 234 TcpStreamWriter.Dispose(); 235 } 236 237 if (streamSocket != null) 238 { 239 streamSocket.Dispose(); 240 } 241 } 242 } 243 }