file360

Log | Files | Refs

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 }