summaryrefslogtreecommitdiffstats
path: root/mDNSResponder/Clients/SimpleChat.NET/SimpleChat.cs
diff options
context:
space:
mode:
Diffstat (limited to 'mDNSResponder/Clients/SimpleChat.NET/SimpleChat.cs')
-rwxr-xr-xmDNSResponder/Clients/SimpleChat.NET/SimpleChat.cs601
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();
+ }
+ };
+}