]> git.saurik.com Git - apple/mdnsresponder.git/blob - Clients/SimpleChat.NET/SimpleChat.cs
32191cbe819b009215150764eb410acf6967addc
[apple/mdnsresponder.git] / Clients / SimpleChat.NET / SimpleChat.cs
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 using System;
19 using System.Drawing;
20 using System.Collections;
21 using System.ComponentModel;
22 using System.Windows.Forms;
23 using System.Net;
24 using System.Net.Sockets;
25 using System.Data;
26 using System.Text;
27 using Bonjour;
28
29 namespace SimpleChat.NET
30 {
31 /// <summary>
32 /// Summary description for Form1.
33 /// </summary>
34 ///
35
36 public class SimpleChat : System.Windows.Forms.Form
37 {
38 private System.Windows.Forms.ComboBox comboBox1;
39 private System.Windows.Forms.TextBox textBox2;
40 private System.Windows.Forms.Button button1;
41 private System.Windows.Forms.Label label1;
42
43 private Bonjour.DNSSDEventManager m_eventManager = null;
44
45 private Bonjour.DNSSDService m_service = null;
46
47 private Bonjour.DNSSDService m_registrar = null;
48
49 private Bonjour.DNSSDService m_browser = null;
50
51 private Bonjour.DNSSDService m_resolver = null;
52 private String m_name;
53
54 private Socket m_socket = null;
55
56 private const int BUFFER_SIZE = 1024;
57
58 public byte[] m_buffer = new byte[BUFFER_SIZE];
59
60 public bool m_complete = false;
61
62 public StringBuilder m_sb = new StringBuilder();
63
64 delegate void ReadMessageCallback(String data);
65
66 ReadMessageCallback m_readMessageCallback;
67 /// <summary>
68 /// Required designer variable.
69 /// </summary>
70 private System.ComponentModel.Container components = null;
71 private System.Windows.Forms.RichTextBox richTextBox1;
72
73 // ServiceRegistered
74 //
75 // Called by DNSServices core as a result of Register()
76 // call
77 //
78
79
80
81 public void
82
83 ServiceRegistered
84
85 (
86
87 DNSSDService service,
88
89 DNSSDFlags flags,
90
91 String name,
92
93 String regType,
94
95 String domain
96
97 )
98
99 {
100
101 m_name = name;
102
103
104
105 try
106
107 {
108
109 m_browser = m_service.Browse(0, 0, "_p2pchat._udp", null, m_eventManager);
110
111 }
112
113 catch
114
115 {
116
117 MessageBox.Show("Browse Failed", "Error");
118
119 Application.Exit();
120
121 }
122
123 }
124
125 //
126 // ServiceFound
127 //
128 // Called by DNSServices core as a result of a Browse call
129 //
130
131 public void
132 ServiceFound
133 (
134 DNSSDService sref,
135 DNSSDFlags flags,
136 uint ifIndex,
137 String serviceName,
138 String regType,
139 String domain
140 )
141 {
142
143 if (serviceName != m_name)
144
145 {
146
147 PeerData peer = new PeerData();
148
149
150
151 peer.InterfaceIndex = ifIndex;
152
153 peer.Name = serviceName;
154
155 peer.Type = regType;
156
157 peer.Domain = domain;
158
159 peer.Address = null;
160
161
162
163 comboBox1.Items.Add(peer);
164
165
166
167 if (comboBox1.Items.Count == 1)
168
169 {
170
171 comboBox1.SelectedIndex = 0;
172
173 }
174
175 }
176 }
177
178
179
180 //
181
182 // ServiceLost
183
184 //
185
186 // Called by DNSServices core as a result of a Browse call
187
188 //
189
190
191
192 public void
193
194 ServiceLost
195
196 (
197
198 DNSSDService sref,
199
200 DNSSDFlags flags,
201
202 uint ifIndex,
203
204 String serviceName,
205
206 String regType,
207
208 String domain
209
210 )
211
212 {
213
214 PeerData peer = new PeerData();
215
216
217
218 peer.InterfaceIndex = ifIndex;
219
220 peer.Name = serviceName;
221
222 peer.Type = regType;
223
224 peer.Domain = domain;
225
226 peer.Address = null;
227
228
229
230 comboBox1.Items.Remove(peer);
231
232 }
233
234 //
235 // ServiceResolved
236 //
237 // Called by DNSServices core as a result of DNSService.Resolve()
238 // call
239 //
240
241
242 public void
243
244 ServiceResolved
245
246 (
247
248 DNSSDService sref,
249
250 DNSSDFlags flags,
251
252 uint ifIndex,
253
254 String fullName,
255
256 String hostName,
257
258 ushort port,
259
260 TXTRecord txtRecord
261
262 )
263 {
264
265 m_resolver.Stop();
266
267 m_resolver = null;
268
269
270
271 PeerData peer = (PeerData)comboBox1.SelectedItem;
272
273
274
275 peer.Port = port;
276
277
278
279 try
280
281 {
282
283 m_resolver = m_service.QueryRecord(0, ifIndex, hostName, DNSSDRRType.kDNSSDType_A, DNSSDRRClass.kDNSSDClass_IN, m_eventManager );
284
285 }
286
287 catch
288
289 {
290
291 MessageBox.Show("QueryRecord Failed", "Error");
292
293 Application.Exit();
294
295 }
296 }
297
298 //
299 // QueryAnswered
300 //
301 // Called by DNSServices core as a result of DNSService.QueryRecord()
302 // call
303 //
304
305 public void
306 QueryAnswered
307 (
308 DNSSDService service,
309 DNSSDFlags flags,
310 uint ifIndex,
311 String fullName,
312 DNSSDRRType rrtype,
313 DNSSDRRClass rrclass,
314 Object rdata,
315 uint ttl
316 )
317 {
318
319 m_resolver.Stop();
320
321 m_resolver = null;
322
323
324
325 PeerData peer = (PeerData) comboBox1.SelectedItem;
326
327
328 uint bits = BitConverter.ToUInt32( (Byte[])rdata, 0);
329 System.Net.IPAddress address = new System.Net.IPAddress(bits);
330
331 peer.Address = address;
332 }
333
334
335
336 public void
337
338 OperationFailed
339
340 (
341
342 DNSSDService service,
343
344 DNSSDError error
345
346 )
347
348 {
349
350 MessageBox.Show("Operation returned an error code " + error, "Error");
351
352 }
353
354
355
356 //
357
358 // OnReadMessage
359
360 //
361
362 // Called when there is data to be read on a socket
363
364 //
365
366 // This is called (indirectly) from OnReadSocket()
367
368 //
369
370 private void
371
372 OnReadMessage
373
374 (
375
376 String msg
377
378 )
379
380 {
381
382 int rgb = 0;
383
384
385
386 for (int i = 0; i < msg.Length && msg[i] != ':'; i++)
387
388 {
389
390 rgb = rgb ^ ((int)msg[i] << (i % 3 + 2) * 8);
391
392 }
393
394
395
396 Color color = Color.FromArgb(rgb & 0x007F7FFF);
397
398 richTextBox1.SelectionColor = color;
399
400 richTextBox1.AppendText(msg + Environment.NewLine);
401
402 }
403
404 //
405 // OnReadSocket
406 //
407 // Called by the .NET core when there is data to be read on a socket
408 //
409 // This is called from a worker thread by the .NET core
410 //
411 private void
412 OnReadSocket
413 (
414 IAsyncResult ar
415 )
416 {
417 try
418 {
419 int read = m_socket.EndReceive(ar);
420
421 if (read > 0)
422 {
423 String msg = Encoding.UTF8.GetString(m_buffer, 0, read);
424 Invoke(m_readMessageCallback, new Object[]{msg});
425 }
426
427 m_socket.BeginReceive(m_buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(OnReadSocket), this);
428 }
429 catch
430 {
431 }
432 }
433
434
435 public SimpleChat()
436 {
437 //
438 // Required for Windows Form Designer support
439 //
440 InitializeComponent();
441
442
443
444 try
445
446 {
447
448 m_service = new DNSSDService();
449
450 }
451
452 catch
453
454 {
455
456 MessageBox.Show("Bonjour Service is not available", "Error");
457
458 Application.Exit();
459
460 }
461
462
463
464 m_eventManager = new DNSSDEventManager();
465
466 m_eventManager.ServiceRegistered += new _IDNSSDEvents_ServiceRegisteredEventHandler(this.ServiceRegistered);
467
468 m_eventManager.ServiceFound += new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound);
469
470 m_eventManager.ServiceLost += new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost);
471
472 m_eventManager.ServiceResolved += new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved);
473
474 m_eventManager.QueryRecordAnswered += new _IDNSSDEvents_QueryRecordAnsweredEventHandler(this.QueryAnswered);
475
476 m_eventManager.OperationFailed += new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed);
477
478 m_readMessageCallback = new ReadMessageCallback(OnReadMessage);
479
480 this.Load += new System.EventHandler(this.Form1_Load);
481
482 this.AcceptButton = button1;
483 }
484
485 /// <summary>
486 /// Clean up any resources being used.
487 /// </summary>
488 protected override void
489 Dispose( bool disposing )
490 {
491 if( disposing )
492 {
493 if (components != null)
494 {
495 components.Dispose();
496 }
497
498 if (m_registrar != null)
499 {
500 m_registrar.Stop();
501 }
502
503 if (m_browser != null)
504 {
505 m_browser.Stop();
506 }
507
508
509
510 if (m_resolver != null)
511
512 {
513
514 m_resolver.Stop();
515
516 }
517
518
519
520 m_eventManager.ServiceFound -= new _IDNSSDEvents_ServiceFoundEventHandler(this.ServiceFound);
521
522 m_eventManager.ServiceLost -= new _IDNSSDEvents_ServiceLostEventHandler(this.ServiceLost);
523
524 m_eventManager.ServiceResolved -= new _IDNSSDEvents_ServiceResolvedEventHandler(this.ServiceResolved);
525
526 m_eventManager.QueryRecordAnswered -= new _IDNSSDEvents_QueryRecordAnsweredEventHandler(this.QueryAnswered);
527
528 m_eventManager.OperationFailed -= new _IDNSSDEvents_OperationFailedEventHandler(this.OperationFailed);
529 }
530 base.Dispose( disposing );
531 }
532
533 #region Windows Form Designer generated code
534 /// <summary>
535 /// Required method for Designer support - do not modify
536 /// the contents of this method with the code editor.
537 /// </summary>
538 private void InitializeComponent()
539 {
540 this.comboBox1 = new System.Windows.Forms.ComboBox();
541 this.textBox2 = new System.Windows.Forms.TextBox();
542 this.button1 = new System.Windows.Forms.Button();
543 this.label1 = new System.Windows.Forms.Label();
544 this.richTextBox1 = new System.Windows.Forms.RichTextBox();
545 this.SuspendLayout();
546 //
547 // comboBox1
548 //
549 this.comboBox1.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
550 | System.Windows.Forms.AnchorStyles.Right);
551 this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
552 this.comboBox1.Location = new System.Drawing.Point(59, 208);
553 this.comboBox1.Name = "comboBox1";
554 this.comboBox1.Size = new System.Drawing.Size(224, 21);
555 this.comboBox1.Sorted = true;
556 this.comboBox1.TabIndex = 5;
557 this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
558 //
559 // textBox2
560 //
561 this.textBox2.Anchor = ((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
562 | System.Windows.Forms.AnchorStyles.Right);
563 this.textBox2.Location = new System.Drawing.Point(8, 248);
564 this.textBox2.Name = "textBox2";
565 this.textBox2.ScrollBars = System.Windows.Forms.ScrollBars.Horizontal;
566 this.textBox2.Size = new System.Drawing.Size(192, 20);
567 this.textBox2.TabIndex = 2;
568 this.textBox2.Text = "";
569 this.textBox2.TextChanged += new System.EventHandler(this.textBox2_TextChanged);
570 //
571 // button1
572 //
573 this.button1.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right);
574 this.button1.Enabled = false;
575 this.button1.Location = new System.Drawing.Point(208, 248);
576 this.button1.Name = "button1";
577 this.button1.TabIndex = 3;
578 this.button1.Text = "Send";
579 this.button1.Click += new System.EventHandler(this.button1_Click);
580 //
581 // label1
582 //
583 this.label1.Anchor = (System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left);
584 this.label1.Location = new System.Drawing.Point(8, 210);
585 this.label1.Name = "label1";
586 this.label1.Size = new System.Drawing.Size(48, 16);
587 this.label1.TabIndex = 4;
588 this.label1.Text = "Talk To:";
589 //
590 // richTextBox1
591 //
592 this.richTextBox1.Anchor = (((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
593 | System.Windows.Forms.AnchorStyles.Left)
594 | System.Windows.Forms.AnchorStyles.Right);
595 this.richTextBox1.Location = new System.Drawing.Point(8, 8);
596 this.richTextBox1.Name = "richTextBox1";
597 this.richTextBox1.ReadOnly = true;
598 this.richTextBox1.Size = new System.Drawing.Size(272, 184);
599 this.richTextBox1.TabIndex = 1;
600 this.richTextBox1.Text = "";
601 //
602 // Form1
603 //
604 this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
605 this.ClientSize = new System.Drawing.Size(292, 273);
606 this.Controls.AddRange(new System.Windows.Forms.Control[] {
607 this.richTextBox1,
608 this.label1,
609 this.button1,
610 this.textBox2,
611 this.comboBox1});
612 this.Name = "Form1";
613 this.Text = "SimpleChat.NET";
614 this.ResumeLayout(false);
615
616 }
617 #endregion
618
619 private void Form1_Load(object sender, EventArgs e)
620 {
621 IPEndPoint localEP = new IPEndPoint(System.Net.IPAddress.Any, 0);
622
623 //
624 // create the socket and bind to INADDR_ANY
625 //
626 m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
627 m_socket.Bind(localEP);
628 localEP = (IPEndPoint) m_socket.LocalEndPoint;
629
630 //
631 // start asynchronous read
632 //
633 m_socket.BeginReceive(m_buffer, 0, BUFFER_SIZE, 0, new AsyncCallback(this.OnReadSocket), this);
634
635 try
636 {
637 //
638 // start the register and browse operations
639 //
640 m_registrar = m_service.Register( 0, 0, System.Environment.UserName, "_p2pchat._udp", null, null, ( ushort ) localEP.Port, null, m_eventManager );
641 }
642 catch
643 {
644 MessageBox.Show("Bonjour service is not available", "Error");
645 Application.Exit();
646 }
647 }
648
649 /// <summary>
650 /// The main entry point for the application.
651 /// </summary>
652 [STAThread]
653 static void Main()
654 {
655 Application.Run(new SimpleChat());
656 }
657
658 //
659 // send the message to a peer
660 //
661 private void button1_Click(object sender, System.EventArgs e)
662 {
663 PeerData peer = (PeerData) comboBox1.SelectedItem;
664
665 String message = m_name + ": " + textBox2.Text;
666
667 Byte[] bytes = Encoding.UTF8.GetBytes(message);
668
669 IPEndPoint endPoint = new IPEndPoint( peer.Address, peer.Port );
670
671
672
673 m_socket.SendTo(bytes, endPoint);
674
675 richTextBox1.SelectionColor = Color.Black;
676
677 richTextBox1.AppendText(textBox2.Text + "\n");
678
679 textBox2.Text = "";
680 }
681
682 //
683 // called when typing in message box
684 //
685 private void textBox2_TextChanged(object sender, System.EventArgs e)
686 {
687 PeerData peer = (PeerData) comboBox1.SelectedItem;
688 button1.Enabled = ((peer.Address != null) && (textBox2.Text.Length > 0));
689 }
690
691 //
692 // called when peer target changes
693 //
694 /// <summary>
695 /// </summary>
696 /// <param name="sender"></param>
697 /// <param name="e"></param>
698 private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e)
699 {
700 PeerData peer = (PeerData) comboBox1.SelectedItem;
701
702 try
703 {
704 m_resolver = m_service.Resolve(0, peer.InterfaceIndex, peer.Name, peer.Type, peer.Domain, m_eventManager);
705 }
706 catch
707 {
708 MessageBox.Show("Unable to Resolve service", "Error");
709 Application.Exit();
710 }
711 }
712 }
713
714
715
716 //
717
718 // PeerData
719
720 //
721
722 // Holds onto the information associated with a peer on the network
723
724 //
725
726 public class PeerData
727
728 {
729
730 public uint InterfaceIndex;
731
732 public String Name;
733
734 public String Type;
735
736 public String Domain;
737
738 public IPAddress Address;
739
740 public int Port;
741
742
743
744 public override String
745
746 ToString()
747
748 {
749
750 return Name;
751
752 }
753
754
755
756 public override bool
757
758 Equals(object other)
759
760 {
761
762 bool result = false;
763
764
765
766 if (other != null)
767
768 {
769
770 if ((object)this == other)
771
772 {
773
774 result = true;
775
776 }
777
778 else if (other is PeerData)
779
780 {
781
782 PeerData otherPeerData = (PeerData)other;
783
784
785
786 result = (this.Name == otherPeerData.Name);
787
788 }
789
790 }
791
792
793
794 return result;
795
796 }
797
798
799
800 public override int
801
802 GetHashCode()
803
804 {
805
806 return Name.GetHashCode();
807
808 }
809
810 };
811 }