X-Git-Url: https://git.saurik.com/apple/mdnsresponder.git/blobdiff_plain/67c8f8a10700c05d2460d60f5927f23cb5cb9241..3c3ba2ccf2a05adfec7aa14b4b82b903a0091afd:/Clients/SimpleChat.NET/SimpleChat.cs diff --git a/Clients/SimpleChat.NET/SimpleChat.cs b/Clients/SimpleChat.NET/SimpleChat.cs index e7f3b1e..32191cb 100755 --- a/Clients/SimpleChat.NET/SimpleChat.cs +++ b/Clients/SimpleChat.NET/SimpleChat.cs @@ -13,31 +13,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - - Change History (most recent first): - -$Log: SimpleChat.cs,v $ -Revision 1.6 2006/08/14 23:24:21 cheshire -Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0 - -Revision 1.5 2004/09/13 19:37:42 shersche -Change code to reflect namespace and type changes to dnssd.NET library - -Revision 1.4 2004/09/11 05:42:56 shersche -don't reset SelectedIndex in OnRemove - -Revision 1.3 2004/09/11 00:38:58 shersche -DNSService APIs now expect port in host format - -Revision 1.2 2004/07/19 22:08:53 shersche -Fixed rdata->int conversion problem in QueryRecordReply - -Revision 1.1 2004/07/19 07:57:08 shersche -Initial revision - - - -*/ + */ using System; using System.Drawing; @@ -48,7 +24,7 @@ using System.Net; using System.Net.Sockets; using System.Data; using System.Text; -using Apple.DNSSD; +using Bonjour; namespace SimpleChat.NET { @@ -57,427 +33,374 @@ namespace SimpleChat.NET /// /// - // - // PeerData - // - // Holds onto the information associated with a peer on the network - // - public class PeerData + public class SimpleChat : System.Windows.Forms.Form { - public int InterfaceIndex; - public String Name; - public String Type; - public String Domain; - public IPAddress Address; - public int Port; - - public override String - ToString() - { - return Name; - } + private System.Windows.Forms.ComboBox comboBox1; + private System.Windows.Forms.TextBox textBox2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Label label1; - public override bool - Equals(object other) - { - bool result = false; + private Bonjour.DNSSDEventManager m_eventManager = null; - if (other != null) - { - if ((object) this == other) - { - result = true; - } - else if (other is PeerData) - { - PeerData otherPeerData = (PeerData) other; + private Bonjour.DNSSDService m_service = null; - result = (this.Name == otherPeerData.Name); - } - } + private Bonjour.DNSSDService m_registrar = null; - return result; - } - - public override int - GetHashCode() - { - return Name.GetHashCode(); - } - }; - - // - // ResolveData - // - // Holds onto the information associated with the resolution - // of a DNSService - // - public class ResolveData - { - public int InterfaceIndex; - public String FullName; - public String HostName; - public int Port; - public Byte[] TxtRecord; - - public override String - ToString() - { - return FullName; - } - }; + private Bonjour.DNSSDService m_browser = null; + private Bonjour.DNSSDService m_resolver = null; + private String m_name; - // - // SocketStateObject - // - // Holds onto the data associated with an asynchronous - // socket operation - // - class SocketStateObject - { - public const int BUFFER_SIZE = 1024; - private Socket m_socket; - public byte[] m_buffer; - public bool m_complete; - public StringBuilder m_sb = new StringBuilder(); + private Socket m_socket = null; - public SocketStateObject(Socket socket) - { - m_buffer = new byte[BUFFER_SIZE]; - m_complete = false; - m_socket = socket; - } + private const int BUFFER_SIZE = 1024; - public Socket - WorkSocket - { - get - { - return m_socket; - } - } - } - public class Form1 : System.Windows.Forms.Form - { - private System.Windows.Forms.ComboBox comboBox1; - private System.Windows.Forms.TextBox textBox2; - private System.Windows.Forms.Button button1; - private System.Windows.Forms.Label label1; - private ServiceRef registrar = null; - private ServiceRef browser = null; - private ServiceRef resolver = null; - private String myName; + public byte[] m_buffer = new byte[BUFFER_SIZE]; + + public bool m_complete = false; + + public StringBuilder m_sb = new StringBuilder(); + + delegate void ReadMessageCallback(String data); + + ReadMessageCallback m_readMessageCallback; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; - - // - // These all of our callbacks. These are invoked in the context - // of the main (GUI) thread. The DNSService callbacks Invoke() - // them - delegate void RegisterServiceCallback(String name); - delegate void AddPeerCallback(PeerData data); - delegate void RemovePeerCallback(PeerData data); - delegate void ResolveServiceCallback(ResolveData data); - delegate void ResolveAddressCallback(System.Net.IPAddress address); - delegate void ReadMessageCallback(String data); - - RegisterServiceCallback registerServiceCallback; - AddPeerCallback addPeerCallback; - RemovePeerCallback removePeerCallback; - ResolveServiceCallback resolveServiceCallback; - ResolveAddressCallback resolveAddressCallback; - ReadMessageCallback readMessageCallback; private System.Windows.Forms.RichTextBox richTextBox1; + // ServiceRegistered // - // The socket that we will be reading data from + // Called by DNSServices core as a result of Register() + // call // - Socket socket = null; - // - // OnRegisterService - // - // The name that we are passed might be different than the - // name we called Register with. So we hold onto this name - // rather than the name we Register with. - // - // This is called (indirectly) from OnRegisterReply(). - // - private void - OnRegisterService - ( - String name - ) - { - myName = name; - } - // - // OnAddPeer - // - // Called when DNSServices detects a new P2P Chat peer has - // joined. - // - // This is called (indirectly) from OnBrowseReply() - // - private void - OnAddPeer - ( - PeerData peer - ) - { - comboBox1.Items.Add(peer); - if (comboBox1.Items.Count == 1) - { - comboBox1.SelectedIndex = 0; - } - } + public void - // - // OnRemovePeer - // - // Called when DNSServices detects a P2P peer has left - // the network - // - // This is called (indirectly) from OnBrowseReply() - // - private void - OnRemovePeer - ( - PeerData peer - ) - { - comboBox1.Items.Remove(peer); - } + ServiceRegistered - // - // OnResolveService - // - // Called when DNSServices has resolved a service. - // - // This is called (indirectly) from OnResolveService() - // - private void - OnResolveService - ( - ResolveData data - ) - { - resolver.Dispose(); + ( - PeerData peer = (PeerData) comboBox1.SelectedItem; + DNSSDService service, - peer.Port = data.Port; + DNSSDFlags flags, - try - { - resolver = DNSService.QueryRecord(0, 0, data.HostName, /* ns_t_a */ 1, /* ns_t_c */ 1, new DNSService.QueryRecordReply(OnQueryRecordReply)); - } - catch - { - MessageBox.Show("QueryRecord Failed", "Error"); - Application.Exit(); - } - } + String name, - // - // OnResolveAddress - // - // Called when DNSServices has finished a query operation - // - // This is called (indirectly) from OnQueryRecordReply() - // - private void - OnResolveAddress - ( - System.Net.IPAddress address - ) - { - resolver.Dispose(); + String regType, - PeerData peer = (PeerData) comboBox1.SelectedItem; + String domain - peer.Address = address; - } + ) - // - // OnReadMessage - // - // Called when there is data to be read on a socket - // - // This is called (indirectly) from OnReadSocket() - // - private void - OnReadMessage - ( - String msg - ) - { - int rgb = 0; + { - for (int i = 0; i < msg.Length && msg[i] != ':'; i++) - { - rgb = rgb ^ ((int) msg[i] << (i % 3 + 2) * 8); - } + m_name = name; - Color color = Color.FromArgb(rgb & 0x007F7FFF); - richTextBox1.SelectionColor = color; - - richTextBox1.AppendText(msg + "\n"); - } - // - // OnRegisterReply - // - // Called by DNSServices core as a result of DNSService.Register() - // call - // - // This is called from a worker thread by DNSService core. - // - private void - OnRegisterReply - ( - ServiceRef sdRef, - ServiceFlags flags, - ErrorCode errorCode, - String name, - String regtype, - String domain) - { - if (errorCode == ErrorCode.NoError) - { - Invoke(registerServiceCallback, new Object[]{name}); - } - else - { - MessageBox.Show("OnRegisterReply returned an error code " + errorCode, "Error"); - } - } + try + { + + m_browser = m_service.Browse(0, 0, "_p2pchat._udp", null, m_eventManager); + + } + + catch + + { + + MessageBox.Show("Browse Failed", "Error"); + + Application.Exit(); + + } + + } // - // OnBrowseReply - // - // Called by DNSServices core as a result of DNSService.Browse() - // call + // ServiceFound // - // This is called from a worker thread by DNSService core. + // Called by DNSServices core as a result of a Browse call // - private void - OnBrowseReply - ( - ServiceRef sdRef, - ServiceFlags flags, - int interfaceIndex, - ErrorCode errorCode, - String name, - String type, - String domain) + + public void + ServiceFound + ( + DNSSDService sref, + DNSSDFlags flags, + uint ifIndex, + String serviceName, + String regType, + String domain + ) { - if (errorCode == ErrorCode.NoError) - { - PeerData peer = new PeerData(); - peer.InterfaceIndex = interfaceIndex; - peer.Name = name; - peer.Type = type; - peer.Domain = domain; - peer.Address = null; + if (serviceName != m_name) - if ((flags & ServiceFlags.Add) != 0) - { - Invoke(addPeerCallback, new Object[]{peer}); - } - else if ((flags == 0) || ((flags & ServiceFlags.MoreComing) != 0)) - { - Invoke(removePeerCallback, new Object[]{peer}); - } - } - else - { - MessageBox.Show("OnBrowseReply returned an error code " + errorCode, "Error"); - } + { + + PeerData peer = new PeerData(); + + + + peer.InterfaceIndex = ifIndex; + + peer.Name = serviceName; + + peer.Type = regType; + + peer.Domain = domain; + + peer.Address = null; + + + + comboBox1.Items.Add(peer); + + + + if (comboBox1.Items.Count == 1) + + { + + comboBox1.SelectedIndex = 0; + + } + + } } + + + // + + // ServiceLost + + // + + // Called by DNSServices core as a result of a Browse call + + // + + + + public void + + ServiceLost + + ( + + DNSSDService sref, + + DNSSDFlags flags, + + uint ifIndex, + + String serviceName, + + String regType, + + String domain + + ) + + { + + PeerData peer = new PeerData(); + + + + peer.InterfaceIndex = ifIndex; + + peer.Name = serviceName; + + peer.Type = regType; + + peer.Domain = domain; + + peer.Address = null; + + + + comboBox1.Items.Remove(peer); + + } + // - // OnResolveReply + // ServiceResolved // // Called by DNSServices core as a result of DNSService.Resolve() // call // - // This is called from a worker thread by DNSService core. - // - private void - OnResolveReply - ( - ServiceRef sdRef, - ServiceFlags flags, - int interfaceIndex, - ErrorCode errorCode, - String fullName, - String hostName, - int port, - Byte[] txtRecord - ) + + + public void + + ServiceResolved + + ( + + DNSSDService sref, + + DNSSDFlags flags, + + uint ifIndex, + + String fullName, + + String hostName, + + ushort port, + + TXTRecord txtRecord + + ) { - if (errorCode == ErrorCode.NoError) - { - ResolveData data = new ResolveData(); - data.InterfaceIndex = interfaceIndex; - data.FullName = fullName; - data.HostName = hostName; - data.Port = port; - data.TxtRecord = txtRecord; + m_resolver.Stop(); - Invoke(resolveServiceCallback, new Object[]{data}); - } - else - { - MessageBox.Show("OnResolveReply returned an error code: " + errorCode, "Error"); - } + m_resolver = null; + + + + PeerData peer = (PeerData)comboBox1.SelectedItem; + + + + peer.Port = port; + + + + try + + { + + m_resolver = m_service.QueryRecord(0, ifIndex, hostName, DNSSDRRType.kDNSSDType_A, DNSSDRRClass.kDNSSDClass_IN, m_eventManager ); + + } + + catch + + { + + MessageBox.Show("QueryRecord Failed", "Error"); + + Application.Exit(); + + } } // - // OnQueryRecordReply + // QueryAnswered // // Called by DNSServices core as a result of DNSService.QueryRecord() // call // - // This is called from a worker thread by DNSService core. - // - private void - OnQueryRecordReply + + public void + QueryAnswered ( - ServiceRef sdRef, - ServiceFlags flags, - int interfaceIndex, - ErrorCode errorCode, - String fullName, - int rrtype, - int rrclass, - Byte[] rdata, - int ttl - ) - { - if (errorCode == ErrorCode.NoError) - { - uint bits = BitConverter.ToUInt32(rdata, 0); - System.Net.IPAddress data = new System.Net.IPAddress(bits); - - Invoke(resolveAddressCallback, new Object[]{data}); - } - else - { - MessageBox.Show("OnQueryRecordReply returned an error code: " + errorCode, "Error"); - } + DNSSDService service, + DNSSDFlags flags, + uint ifIndex, + String fullName, + DNSSDRRType rrtype, + DNSSDRRClass rrclass, + Object rdata, + uint ttl + ) + { + + m_resolver.Stop(); + + m_resolver = null; + + + + PeerData peer = (PeerData) comboBox1.SelectedItem; + + + uint bits = BitConverter.ToUInt32( (Byte[])rdata, 0); + System.Net.IPAddress address = new System.Net.IPAddress(bits); + + peer.Address = address; } + + + public void + + OperationFailed + + ( + + DNSSDService service, + + DNSSDError error + + ) + + { + + MessageBox.Show("Operation returned an error code " + error, "Error"); + + } + + + + // + + // OnReadMessage + + // + + // Called when there is data to be read on a socket + + // + + // This is called (indirectly) from OnReadSocket() + + // + + private void + + OnReadMessage + + ( + + String msg + + ) + + { + + int rgb = 0; + + + + for (int i = 0; i < msg.Length && msg[i] != ':'; i++) + + { + + rgb = rgb ^ ((int)msg[i] << (i % 3 + 2) * 8); + + } + + + + Color color = Color.FromArgb(rgb & 0x007F7FFF); + + richTextBox1.SelectionColor = color; + + richTextBox1.AppendText(msg + Environment.NewLine); + + } + // // OnReadSocket // @@ -491,26 +414,17 @@ namespace SimpleChat.NET IAsyncResult ar ) { - SocketStateObject so = (SocketStateObject) ar.AsyncState; - Socket s = so.WorkSocket; - try { - if (s == null) - { - return; - } - - int read = s.EndReceive(ar); + int read = m_socket.EndReceive(ar); if (read > 0) { - String msg = Encoding.UTF8.GetString(so.m_buffer, 0, read); - - Invoke(readMessageCallback, new Object[]{msg}); + String msg = Encoding.UTF8.GetString(m_buffer, 0, read); + Invoke(m_readMessageCallback, new Object[]{msg}); } - s.BeginReceive(so.m_buffer, 0, SocketStateObject.BUFFER_SIZE, 0, new AsyncCallback(OnReadSocket), so); + m_socket.BeginReceive(m_buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(OnReadSocket), this); } catch { @@ -518,19 +432,50 @@ namespace SimpleChat.NET } - public Form1() + public SimpleChat() { // // Required for Windows Form Designer support // InitializeComponent(); - registerServiceCallback = new RegisterServiceCallback(OnRegisterService); - addPeerCallback = new AddPeerCallback(OnAddPeer); - removePeerCallback = new RemovePeerCallback(OnRemovePeer); - resolveServiceCallback = new ResolveServiceCallback(OnResolveService); - resolveAddressCallback = new ResolveAddressCallback(OnResolveAddress); - readMessageCallback = new ReadMessageCallback(OnReadMessage); + + + try + + { + + m_service = new DNSSDService(); + + } + + catch + + { + + MessageBox.Show("Bonjour Service is not available", "Error"); + + Application.Exit(); + + } + + + + m_eventManager = new DNSSDEventManager(); + + m_eventManager.ServiceRegistered += new _IDNSSDEvents_ServiceRegisteredEventHandler(this.ServiceRegistered); + + m_eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound); + + m_eventManager.ServiceLost += new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost); + + m_eventManager.ServiceResolved += new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved); + + m_eventManager.QueryRecordAnswered += new _IDNSSDEvents_QueryRecordAnsweredEventHandler(this.QueryAnswered); + + m_eventManager.OperationFailed += new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed); + + m_readMessageCallback = new ReadMessageCallback(OnReadMessage); this.Load += new System.EventHandler(this.Form1_Load); @@ -550,15 +495,37 @@ namespace SimpleChat.NET components.Dispose(); } - if (registrar != null) + if (m_registrar != null) { - registrar.Dispose(); + m_registrar.Stop(); } - if (browser != null) + if (m_browser != null) { - browser.Dispose(); + m_browser.Stop(); } + + + + if (m_resolver != null) + + { + + m_resolver.Stop(); + + } + + + + m_eventManager.ServiceFound -= new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound); + + m_eventManager.ServiceLost -= new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost); + + m_eventManager.ServiceResolved -= new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved); + + m_eventManager.QueryRecordAnswered -= new _IDNSSDEvents_QueryRecordAnsweredEventHandler(this.QueryAnswered); + + m_eventManager.OperationFailed -= new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed); } base.Dispose( disposing ); } @@ -656,27 +623,25 @@ namespace SimpleChat.NET // // create the socket and bind to INADDR_ANY // - socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); - socket.Bind(localEP); - localEP = (IPEndPoint) socket.LocalEndPoint; + m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + m_socket.Bind(localEP); + localEP = (IPEndPoint) m_socket.LocalEndPoint; // // start asynchronous read // - SocketStateObject so = new SocketStateObject(socket); - socket.BeginReceive(so.m_buffer, 0, SocketStateObject.BUFFER_SIZE, 0, new AsyncCallback(this.OnReadSocket), so); + m_socket.BeginReceive(m_buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(this.OnReadSocket), this); try { // // start the register and browse operations // - registrar = DNSService.Register(0, 0, System.Environment.UserName, "_p2pchat._udp", null, null, localEP.Port, null, new DNSService.RegisterReply(OnRegisterReply)); - browser = DNSService.Browse(0, 0, "_p2pchat._udp", null, new DNSService.BrowseReply(OnBrowseReply)); + m_registrar = m_service.Register( 0, 0, System.Environment.UserName, "_p2pchat._udp", null, null, ( ushort ) localEP.Port, null, m_eventManager ); } catch { - MessageBox.Show("DNSServices Not Available", "Error"); + MessageBox.Show("Bonjour service is not available", "Error"); Application.Exit(); } } @@ -687,7 +652,7 @@ namespace SimpleChat.NET [STAThread] static void Main() { - Application.Run(new Form1()); + Application.Run(new SimpleChat()); } // @@ -697,13 +662,15 @@ namespace SimpleChat.NET { PeerData peer = (PeerData) comboBox1.SelectedItem; - String message = myName + ": " + textBox2.Text; + String message = m_name + ": " + textBox2.Text; Byte[] bytes = Encoding.UTF8.GetBytes(message); - - UdpClient udpSocket = new UdpClient(peer.Address.ToString(), peer.Port); - udpSocket.Send(bytes, bytes.Length); + IPEndPoint endPoint = new IPEndPoint( peer.Address, peer.Port ); + + + + m_socket.SendTo(bytes, endPoint); richTextBox1.SelectionColor = Color.Black; @@ -718,15 +685,7 @@ namespace SimpleChat.NET private void textBox2_TextChanged(object sender, System.EventArgs e) { PeerData peer = (PeerData) comboBox1.SelectedItem; - - if ((peer.Address != null) && (textBox2.Text.Length > 0)) - { - button1.Enabled = true; - } - else - { - button1.Enabled = false; - } + button1.Enabled = ((peer.Address != null) && (textBox2.Text.Length > 0)); } // @@ -742,7 +701,7 @@ namespace SimpleChat.NET try { - resolver = DNSService.Resolve(0, 0, peer.Name, peer.Type, peer.Domain, new DNSService.ResolveReply(OnResolveReply)); + m_resolver = m_service.Resolve(0, peer.InterfaceIndex, peer.Name, peer.Type, peer.Domain, m_eventManager); } catch { @@ -751,4 +710,102 @@ namespace SimpleChat.NET } } } + + + + // + + // PeerData + + // + + // Holds onto the information associated with a peer on the network + + // + + public class PeerData + + { + + public uint InterfaceIndex; + + public String Name; + + public String Type; + + public String Domain; + + public IPAddress Address; + + public int Port; + + + + public override String + + ToString() + + { + + return Name; + + } + + + + public override bool + + Equals(object other) + + { + + bool result = false; + + + + if (other != null) + + { + + if ((object)this == other) + + { + + result = true; + + } + + else if (other is PeerData) + + { + + PeerData otherPeerData = (PeerData)other; + + + + result = (this.Name == otherPeerData.Name); + + } + + } + + + + return result; + + } + + + + public override int + + GetHashCode() + + { + + return Name.GetHashCode(); + + } + + }; }