diff options
Diffstat (limited to 'mDNSResponder/Clients/SimpleChat.NET/SimpleChat.cs')
-rwxr-xr-x | mDNSResponder/Clients/SimpleChat.NET/SimpleChat.cs | 601 |
1 files changed, 601 insertions, 0 deletions
diff --git a/mDNSResponder/Clients/SimpleChat.NET/SimpleChat.cs b/mDNSResponder/Clients/SimpleChat.NET/SimpleChat.cs new file mode 100755 index 00000000..338bdb78 --- /dev/null +++ b/mDNSResponder/Clients/SimpleChat.NET/SimpleChat.cs @@ -0,0 +1,601 @@ +/* -*- Mode: C; tab-width: 4 -*- + * + * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +using System; +using System.Drawing; +using System.Collections; +using System.ComponentModel; +using System.Windows.Forms; +using System.Net; +using System.Net.Sockets; +using System.Data; +using System.Text; +using Bonjour; + +namespace SimpleChat.NET +{ + /// <summary> + /// Summary description for Form1. + /// </summary> + /// + + public class SimpleChat : 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 Bonjour.DNSSDEventManager m_eventManager = null; + private Bonjour.DNSSDService m_service = null; + private Bonjour.DNSSDService m_registrar = null; + private Bonjour.DNSSDService m_browser = null; + private Bonjour.DNSSDService m_resolver = null; + private String m_name; + private Socket m_socket = null; + private const int BUFFER_SIZE = 1024; + 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; + /// <summary> + /// Required designer variable. + /// </summary> + private System.ComponentModel.Container components = null; + private System.Windows.Forms.RichTextBox richTextBox1; + + // ServiceRegistered + // + // Called by DNSServices core as a result of Register() + // call + // + public void + ServiceRegistered + ( + DNSSDService service, + DNSSDFlags flags, + String name, + String regType, + String domain + ) + { + m_name = name; + + // + // Try to start browsing for other instances of this service + // + try + { + m_browser = m_service.Browse(0, 0, "_p2pchat._udp", null, m_eventManager); + } + catch + { + MessageBox.Show("Browse Failed", "Error"); + Application.Exit(); + } + } + + // + // ServiceFound + // + // Called by DNSServices core as a result of a Browse call + // + public void + ServiceFound + ( + DNSSDService sref, + DNSSDFlags flags, + uint ifIndex, + String serviceName, + String regType, + String domain + ) + { + if (serviceName != m_name) + { + 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); + } + + // + // ServiceResolved + // + // Called by DNSServices core as a result of DNSService.Resolve() + // call + // + public void + ServiceResolved + ( + DNSSDService sref, + DNSSDFlags flags, + uint ifIndex, + String fullName, + String hostName, + ushort port, + TXTRecord txtRecord + ) + { + m_resolver.Stop(); + m_resolver = null; + + PeerData peer = (PeerData)comboBox1.SelectedItem; + + peer.Port = port; + + // + // Query for the IP address associated with "hostName" + // + 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(); + } + } + + // + // QueryAnswered + // + // Called by DNSServices core as a result of DNSService.QueryRecord() + // call + // + public void + QueryAnswered + ( + DNSSDService service, + DNSSDFlags flags, + uint ifIndex, + String fullName, + DNSSDRRType rrtype, + DNSSDRRClass rrclass, + Object rdata, + uint ttl + ) + { + // + // Stop the resolve to reduce the burden on the network + // + 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 + // + // Called by the .NET core when there is data to be read on a socket + // + // This is called from a worker thread by the .NET core + // + private void + OnReadSocket + ( + IAsyncResult ar + ) + { + try + { + int read = m_socket.EndReceive(ar); + + if (read > 0) + { + String msg = Encoding.UTF8.GetString(m_buffer, 0, read); + Invoke(m_readMessageCallback, new Object[]{msg}); + } + + m_socket.BeginReceive(m_buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(OnReadSocket), this); + } + catch + { + } + } + + + public SimpleChat() + { + // + // Required for Windows Form Designer support + // + InitializeComponent(); + + try + { + m_service = new DNSSDService(); + } + catch + { + MessageBox.Show("Bonjour Service is not available", "Error"); + Application.Exit(); + } + + // + // Associate event handlers with all the Bonjour events that the app is interested in. + // + 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); + + // + // Socket read handler + // + m_readMessageCallback = new ReadMessageCallback(OnReadMessage); + + this.Load += new System.EventHandler(this.Form1_Load); + + this.AcceptButton = button1; + } + + /// <summary> + /// Clean up any resources being used. + /// </summary> + protected override void + Dispose( bool disposing ) + { + if( disposing ) + { + if (components != null) + { + components.Dispose(); + } + + if (m_registrar != null) + { + m_registrar.Stop(); + } + + if (m_browser != null) + { + 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 ); + } + + #region Windows Form Designer generated code + /// <summary> + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// </summary> + private void InitializeComponent() + { + this.comboBox1 = new System.Windows.Forms.ComboBox(); + this.textBox2 = new System.Windows.Forms.TextBox(); + this.button1 = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); + this.richTextBox1 = new System.Windows.Forms.RichTextBox(); + this.SuspendLayout(); + // + // comboBox1 + // + this.comboBox1.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right); + this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.comboBox1.Location = new System.Drawing.Point(59, 208); + this.comboBox1.Name = "comboBox1"; + this.comboBox1.Size = new System.Drawing.Size(224, 21); + this.comboBox1.Sorted = true; + this.comboBox1.TabIndex = 5; + this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); + // + // textBox2 + // + this.textBox2.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right); + this.textBox2.Location = new System.Drawing.Point(8, 248); + this.textBox2.Name = "textBox2"; + this.textBox2.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal; + this.textBox2.Size = new System.Drawing.Size(192, 20); + this.textBox2.TabIndex = 2; + this.textBox2.Text = ""; + this.textBox2.TextChanged += new System.EventHandler(this.textBox2_TextChanged); + // + // button1 + // + this.button1.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right); + this.button1.Enabled = false; + this.button1.Location = new System.Drawing.Point(208, 248); + this.button1.Name = "button1"; + this.button1.TabIndex = 3; + this.button1.Text = "Send"; + this.button1.Click += new System.EventHandler(this.button1_Click); + // + // label1 + // + this.label1.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left); + this.label1.Location = new System.Drawing.Point(8, 210); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(48, 16); + this.label1.TabIndex = 4; + this.label1.Text = "Talk To:"; + // + // richTextBox1 + // + this.richTextBox1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right); + this.richTextBox1.Location = new System.Drawing.Point(8, 8); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.ReadOnly = true; + this.richTextBox1.Size = new System.Drawing.Size(272, 184); + this.richTextBox1.TabIndex = 1; + this.richTextBox1.Text = ""; + // + // Form1 + // + this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); + this.ClientSize = new System.Drawing.Size(292, 273); + this.Controls.AddRange(new System.Windows.Forms.Control[] { + this.richTextBox1, + this.label1, + this.button1, + this.textBox2, + this.comboBox1}); + this.Name = "Form1"; + this.Text = "SimpleChat.NET"; + this.ResumeLayout(false); + + } + #endregion + + private void Form1_Load(object sender, EventArgs e) + { + IPEndPoint localEP = new IPEndPoint(System.Net.IPAddress.Any, 0); + + // + // create the socket and bind to INADDR_ANY + // + m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + m_socket.Bind(localEP); + localEP = (IPEndPoint) m_socket.LocalEndPoint; + + // + // start asynchronous read + // + m_socket.BeginReceive(m_buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(this.OnReadSocket), this); + + try + { + // + // start the register and browse operations + // + m_registrar = m_service.Register( 0, 0, System.Environment.UserName, "_p2pchat._udp", null, null, ( ushort ) localEP.Port, null, m_eventManager ); + } + catch + { + MessageBox.Show("Bonjour service is not available", "Error"); + Application.Exit(); + } + } + + /// <summary> + /// The main entry point for the application. + /// </summary> + [STAThread] + static void Main() + { + Application.Run(new SimpleChat()); + } + + // + // send the message to a peer + // + private void button1_Click(object sender, System.EventArgs e) + { + PeerData peer = (PeerData) comboBox1.SelectedItem; + + String message = m_name + ": " + textBox2.Text; + + Byte[] bytes = Encoding.UTF8.GetBytes(message); + + IPEndPoint endPoint = new IPEndPoint( peer.Address, peer.Port ); + + + + m_socket.SendTo(bytes, endPoint); + + richTextBox1.SelectionColor = Color.Black; + + richTextBox1.AppendText(textBox2.Text + "\n"); + + textBox2.Text = ""; + } + + // + // called when typing in message box + // + private void textBox2_TextChanged(object sender, System.EventArgs e) + { + PeerData peer = (PeerData) comboBox1.SelectedItem; + button1.Enabled = ((peer.Address != null) && (textBox2.Text.Length > 0)); + } + + // + // called when peer target changes + // + /// <summary> + /// </summary> + /// <param name="sender"></param> + /// <param name="e"></param> + private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e) + { + PeerData peer = (PeerData) comboBox1.SelectedItem; + + try + { + m_resolver = m_service.Resolve(0, peer.InterfaceIndex, peer.Name, peer.Type, peer.Domain, m_eventManager); + } + catch + { + MessageBox.Show("Unable to Resolve service", "Error"); + Application.Exit(); + } + } + } + + // + // 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(); + } + }; +} |