mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-06-15 12:13:28 +08:00

The sources can be obtained via: http://opensource.apple.com/tarballs/mDNSResponder/mDNSResponder-544.tar.gz
602 lines
17 KiB
C
Executable File
602 lines
17 KiB
C
Executable File
/* -*- 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();
|
|
}
|
|
};
|
|
}
|