2012-01-16 4 views
0

이 클래스는 인터넷에서 발견되었지만 예제 사용법은 없습니다. 나는 그것을 읽고, <events>는 나를 혼란스럽게한다. 나는 심지어 irc.DataRead+=new EventHandler<DataReadEventArgs>(irc_DataRead);이 클래스의 사용 예제

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 
using System.Threading; 

namespace asynchronous 
{ 

    /// <summary> 
    /// Represents an asynchronous Tcp Client. 
    /// </summary> 
    public class Client 
    { 
     /// <summary> 
     /// The default length for the read buffer. 
     /// </summary> 
     private const int DefaultClientReadBufferLength = 4096; 

     /// <summary> 
     /// The tcp client used for the outgoing connection. 
     /// </summary> 
     private readonly TcpClient client; 

     /// <summary> 
     /// The port to connect to on the remote server. 
     /// </summary> 
     private readonly int port; 

     /// <summary> 
     /// A reset event for use if a DNS lookup is required. 
     /// </summary> 
     private readonly ManualResetEvent dnsGetHostAddressesResetEvent = null; 

     /// <summary> 
     /// The length of the read buffer. 
     /// </summary> 
     private readonly int clientReadBufferLength; 

     /// <summary> 
     /// The addresses to try connection to. 
     /// </summary> 
     private IPAddress[] addresses; 

     /// <summary> 
     /// How many times to retry connection. 
     /// </summary> 
     private int retries; 

     /// <summary> 
     /// Occurs when the client connects to the server. 
     /// </summary> 
     public event EventHandler Connected; 

     /// <summary> 
     /// Occurs when the client disconnects from the server. 
     /// </summary> 
     public event EventHandler Disconnected; 

     /// <summary> 
     /// Occurs when data is read by the client. 
     /// </summary> 
     public event EventHandler<DataReadEventArgs> DataRead; 

     /// <summary> 
     /// Occurs when data is written by the client. 
     /// </summary> 
     public event EventHandler<DataWrittenEventArgs> DataWritten; 

     /// <summary> 
     /// Occurs when an exception is thrown during connection. 
     /// </summary> 
     public event EventHandler<ExceptionEventArgs> ClientConnectException; 

     /// <summary> 
     /// Occurs when an exception is thrown while reading data. 
     /// </summary> 
     public event EventHandler<ExceptionEventArgs> ClientReadException; 

     /// <summary> 
     /// Occurs when an exception is thrown while writing data. 
     /// </summary> 
     public event EventHandler<ExceptionEventArgs> ClientWriteException; 

     /// <summary> 
     /// Occurs when an exception is thrown while performing the DNS lookup. 
     /// </summary> 
     public event EventHandler<ExceptionEventArgs> DnsGetHostAddressesException; 

     /// <summary> 
     /// Constructor for a new client object based on a host name or server address string and a port. 
     /// </summary> 
     /// <param name="hostNameOrAddress">The host name or address of the server as a string.</param> 
     /// <param name="port">The port on the server to connect to.</param> 
     /// <param name="clientReadBufferLength">The clients read buffer length.</param> 
     public Client(string hostNameOrAddress, int port, int clientReadBufferLength = DefaultClientReadBufferLength) 
      : this(port, clientReadBufferLength) 
     { 
      this.dnsGetHostAddressesResetEvent = new ManualResetEvent(false); 
      Dns.BeginGetHostAddresses(hostNameOrAddress, this.DnsGetHostAddressesCallback, null); 
     } 

     /// <summary> 
     /// Constructor for a new client object based on a number of IP Addresses and a port. 
     /// </summary> 
     /// <param name="addresses">The IP Addresses to try connecting to.</param> 
     /// <param name="port">The port on the server to connect to.</param> 
     /// <param name="clientReadBufferLength">The clients read buffer length.</param> 
     public Client(IPAddress[] addresses, int port, int clientReadBufferLength = DefaultClientReadBufferLength) 
      : this(port, clientReadBufferLength) 
     { 
      this.addresses = addresses; 
     } 

     /// <summary> 
     /// Constructor for a new client object based on a single IP Address and a port. 
     /// </summary> 
     /// <param name="address">The IP Address to try connecting to.</param> 
     /// <param name="port">The port on the server to connect to.</param> 
     /// <param name="clientReadBufferLength">The clients read buffer length.</param> 
     public Client(IPAddress address, int port, int clientReadBufferLength = DefaultClientReadBufferLength) 
      : this(new[] { address }, port, clientReadBufferLength) 
     { 
     } 

     /// <summary> 
     /// Private constructor for a new client object. 
     /// </summary> 
     /// <param name="port">The port on the server to connect to.</param> 
     /// <param name="clientReadBufferLength">The clients read buffer length.</param> 
     private Client(int port, int clientReadBufferLength) 
     { 
      this.client = new TcpClient(); 
      this.port = port; 
      this.clientReadBufferLength = clientReadBufferLength; 
     } 

     /// <summary> 
     /// Starts an asynchronous connection to the remote server. 
     /// </summary> 
     public void Connect() 
     { 
      if (this.dnsGetHostAddressesResetEvent != null) 
       this.dnsGetHostAddressesResetEvent.WaitOne(); 
      this.retries = 0; 
      this.client.BeginConnect(this.addresses, this.port, this.ClientConnectCallback, null); 
     } 

     /// <summary> 
     /// Writes a string to the server using a given encoding. 
     /// </summary> 
     /// <param name="value">The string to write.</param> 
     /// <param name="encoding">The encoding to use.</param> 
     /// <returns>A Guid that can be used to match the data written to the confirmation event.</returns> 
     public Guid Write(string value, Encoding encoding) 
     { 
      byte[] buffer = encoding.GetBytes(value); 
      return this.Write(buffer); 
     } 

     /// <summary> 
     /// Writes a byte array to the server. 
     /// </summary> 
     /// <param name="buffer">The byte array to write.</param> 
     /// <returns>A Guid that can be used to match the data written to the confirmation event.</returns> 
     public Guid Write(byte[] buffer) 
     { 
      Guid guid = Guid.NewGuid(); 
      NetworkStream networkStream = this.client.GetStream(); 
      networkStream.BeginWrite(buffer, 0, buffer.Length, this.ClientWriteCallback, guid); 
      return guid; 
     } 

     /// <summary> 
     /// Callback from the asynchronous DNS lookup. 
     /// </summary> 
     /// <param name="asyncResult">The result of the async operation.</param> 
     private void DnsGetHostAddressesCallback(IAsyncResult asyncResult) 
     { 
      try 
      { 
       this.addresses = Dns.EndGetHostAddresses(asyncResult); 
       this.dnsGetHostAddressesResetEvent.Set(); 
      } 
      catch (Exception ex) 
      { 
       if (this.DnsGetHostAddressesException != null) 
        this.DnsGetHostAddressesException(this, new ExceptionEventArgs(ex)); 
      } 
     } 

     /// <summary> 
     /// Callback from the asynchronous Connect method. 
     /// </summary> 
     /// <param name="asyncResult">The result of the async operation.</param> 
     private void ClientConnectCallback(IAsyncResult asyncResult) 
     { 
      try 
      { 
       this.client.EndConnect(asyncResult); 
       if (this.Connected != null) 
        this.Connected(this, new EventArgs()); 
      } 
      catch (Exception ex) 
      { 
       retries++; 
       if (retries < 3) 
       { 
        this.client.BeginConnect(this.addresses, this.port, this.ClientConnectCallback, null); 
       } 
       else 
       { 
        if (this.ClientConnectException != null) 
         this.ClientConnectException(this, new ExceptionEventArgs(ex)); 
       } 
       return; 
      } 

      try 
      { 
       NetworkStream networkStream = this.client.GetStream(); 
       byte[] buffer = new byte[this.clientReadBufferLength]; 
       networkStream.BeginRead(buffer, 0, buffer.Length, this.ClientReadCallback, buffer); 
      } 
      catch (Exception ex) 
      { 
       if (this.ClientReadException != null) 
        this.ClientReadException(this, new ExceptionEventArgs(ex)); 
      } 
     } 

     /// <summary> 
     /// Callback from the asynchronous Read method. 
     /// </summary> 
     /// <param name="asyncResult">The result of the async operation.</param> 
     private void ClientReadCallback(IAsyncResult asyncResult) 
     { 
      try 
      { 
       NetworkStream networkStream = this.client.GetStream(); 
       int read = networkStream.EndRead(asyncResult); 

       if (read == 0) 
       { 
        if (this.Disconnected != null) 
         this.Disconnected(this, new EventArgs()); 
       } 

       byte[] buffer = asyncResult.AsyncState as byte[]; 
       if (buffer != null) 
       { 
        byte[] data = new byte[read]; 
        Buffer.BlockCopy(buffer, 0, data, 0, read); 
        networkStream.BeginRead(buffer, 0, buffer.Length, this.ClientReadCallback, buffer); 
        if (this.DataRead != null) 
         this.DataRead(this, new DataReadEventArgs(data)); 
       } 
      } 
      catch (Exception ex) 
      { 
       if (this.ClientReadException != null) 
        this.ClientReadException(this, new ExceptionEventArgs(ex)); 
      } 
     } 

     /// <summary> 
     /// Callback from the asynchronous write callback. 
     /// </summary> 
     /// <param name="asyncResult">The result of the async operation.</param> 
     private void ClientWriteCallback(IAsyncResult asyncResult) 
     { 
      try 
      { 
       NetworkStream networkStream = this.client.GetStream(); 
       networkStream.EndWrite(asyncResult); 
       Guid guid = (Guid)asyncResult.AsyncState; 
       if (this.DataWritten != null) 
        this.DataWritten(this, new DataWrittenEventArgs(guid)); 
      } 
      catch (Exception ex) 
      { 
       if (this.ClientWriteException != null) 
        this.ClientWriteException(this, new ExceptionEventArgs(ex)); 
      } 
     } 
    } 

    /// <summary> 
    /// Provides data for an exception occuring event. 
    /// </summary> 
    public class ExceptionEventArgs : EventArgs 
    { 
     /// <summary> 
     /// Constructor for a new Exception Event Args object. 
     /// </summary> 
     /// <param name="ex">The exception that was thrown.</param> 
     public ExceptionEventArgs(Exception ex) 
     { 
      this.Exception = ex; 
     } 

     public Exception Exception { get; private set; } 
    } 

    /// <summary> 
    /// Provides data for a data read event. 
    /// </summary> 
    public class DataReadEventArgs : EventArgs 
    { 
     /// <summary> 
     /// Constructor for a new Data Read Event Args object. 
     /// </summary> 
     /// <param name="data">The data that was read from the remote host.</param> 
     public DataReadEventArgs(byte[] data) 
     { 
      this.Data = data; 
     } 

     /// <summary> 
     /// Gets the data that has been read. 
     /// </summary> 
     public byte[] Data { get; private set; } 
    } 

    /// <summary> 
    /// Provides data for a data write event. 
    /// </summary> 
    public class DataWrittenEventArgs : EventArgs 
    { 
     /// <summary> 
     /// Constructor for a Data Written Event Args object. 
     /// </summary> 
     /// <param name="guid">The guid of the data written.</param> 
     public DataWrittenEventArgs(Guid guid) 
     { 
      this.Guid = guid; 
     } 

     /// <summary> 
     /// Gets the Guid used to match the data written to the confirmation event. 
     /// </summary> 
     public Guid Guid { get; private set; } 
    } 
} 

후에는 null를 유지하는 이벤트를 초기화 할 때이 내가 시도했지만 나는 그것을 얻지 않는 것입니다. C#을 처음 사용했습니다. # :

using System; 
using System.Text; 
using System.Threading; 

namespace asynchronous 
{ 
    class Program 
    { 
     private static EventHandler connection; 
     private static EventHandler<DataReadEventArgs> irc_DataRead; 
     static void Main(string[] args) 
     { 
      var irc = new Client("irc.rizon.net", 6667); 
      Console.WriteLine("Connecting..."); 
      irc.Connect(); 
      Thread.Sleep(2000); 
      irc.Write("Test", Encoding.UTF8); 
      irc.DataRead+=new EventHandler<DataReadEventArgs>(irc_DataRead); 
      Console.WriteLine(irc_DataRead); 
      Console.WriteLine("Connected."); 
      Console.ReadLine(); 
     } 
    } 
} 

누군가가 IRC에 연결하여 텍스트를 읽고 쓸 수 있도록 도와 줄 수 있습니까?

+0

본 적이 있습니까? http://www.meebey.net/projects/smartirc4net/ –

+0

나는 그렇지 않다. smartirc4net이 비동기식인지 알기나? 채널에 많은 피어가 있기 때문에 비동기 연결이 필요했습니다. – Ryan

+0

RFC 2812는 '서버와 클라이언트는 서로 다른 메시지를 보내고 응답을 생성 할 수도 생성하지 않을 수도 있습니다'라고 말하면서 IRC가 본질적으로 비동기임을 암시합니다. 그러므로, 좋은 기회가 있습니다. –

답변

1

여기서 이벤트 처리기의 null 인스턴스를 이벤트에 연결합니다. 이 작업을 수행하려면 실제 메서드/lambda를 연결해야합니다. 다음을 시도하십시오

static void OnDataRead(object sender, DataReadEventArgs e) { 
    // Data reads call this method 
} 


static void Main(string[] args) { 
    ... 
    irc.DataRead += OnDataRead; 
    ... 
} 
+0

감사합니다. Jared :) – Ryan