From b18c6889362681f3b3b307817fe12d719ab5eb3d Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Fri, 10 May 2013 16:44:19 +0200 Subject: [PATCH] added CDiscover: searching the network for running vocaluxe server, could be useful for users who do not know what a ip address is. --- .../AndroidRemote/AndroidRemote.csproj | 3 + ClientServerLib/ClientServerLib/CDiscover.cs | 120 ++++++++++++++++++ .../ClientServerLib/ClientServerLib.csproj | 1 + .../ClientServerLib/Vocaluxe/CCommands.cs | 2 + .../ClientTest/ClientTest.Designer.cs | 39 ++++++ ClientServerLib/ClientTest/ClientTest.cs | 21 +++ Output/ClientServerLib.dll | Bin 41472 -> 43520 bytes Vocaluxe/Base/Server/CVocaluxeServer.cs | 6 + 8 files changed, 192 insertions(+) create mode 100644 ClientServerLib/ClientServerLib/CDiscover.cs diff --git a/ClientServerLib/AndroidRemote/AndroidRemote.csproj b/ClientServerLib/AndroidRemote/AndroidRemote.csproj index a5f49241..91c8cc78 100644 --- a/ClientServerLib/AndroidRemote/AndroidRemote.csproj +++ b/ClientServerLib/AndroidRemote/AndroidRemote.csproj @@ -76,6 +76,9 @@ ClientServerLib\Vocaluxe\VocaluxeStructs.cs + + ClientServerLib\CDiscover.cs + diff --git a/ClientServerLib/ClientServerLib/CDiscover.cs b/ClientServerLib/ClientServerLib/CDiscover.cs new file mode 100644 index 00000000..2242cf92 --- /dev/null +++ b/ClientServerLib/ClientServerLib/CDiscover.cs @@ -0,0 +1,120 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Timers; + +namespace ClientServerLib +{ + public delegate void OnServerDiscovered(string IPAddress, string Hostname); + + public class CDiscover + { + private string _Keyword; + private string _BroadcastAddress; + private int _Port; + + private Thread _DiscoverThread; + private bool _DiscoverRunning; + private OnServerDiscovered _OnDiscovered; + + + private System.Timers.Timer _BroadcastTimer; + + public CDiscover(int Port, string Keyword, string BroadcastAddress = "255.255.255.255") + { + _BroadcastAddress = BroadcastAddress; + _Port = Port; + _Keyword = Keyword; + + _DiscoverRunning = false; + _BroadcastTimer = new System.Timers.Timer(); + _BroadcastTimer.Elapsed += new ElapsedEventHandler(OnBroadcastEvent); + _BroadcastTimer.Interval = 2500; + } + + public void StartBroadcasting() + { + _BroadcastTimer.Start(); + } + + public void Stop() + { + _BroadcastTimer.Stop(); + _DiscoverRunning = false; + } + + public void Discover(OnServerDiscovered OnDiscovered, int Timeout = 5000) + { + if (_DiscoverRunning) + return; + + _DiscoverRunning = true; + _DiscoverThread = new Thread(() => _Discover(Timeout)); + _OnDiscovered = OnDiscovered; + _DiscoverThread.Start(); + } + + private void OnBroadcastEvent(object source, ElapsedEventArgs e) + { + Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); + s.EnableBroadcast = true; + IPAddress broadcast = IPAddress.Parse(_BroadcastAddress); + byte[] sendbuf = Encoding.UTF8.GetBytes(_Keyword); + IPEndPoint ep = new IPEndPoint(broadcast, _Port); + + s.SendTo(sendbuf, ep); + s.Close(); + } + + private void _Discover(int Timeout) + { + UdpClient listener = null; + Stopwatch timer = new Stopwatch(); + + List knownServer = new List(); + bool foundSomething = false; + timer.Start(); + while (_DiscoverRunning && timer.ElapsedMilliseconds < Timeout * 2) + { + try + { + listener = new UdpClient(_Port); + IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, _Port); + listener.Client.ReceiveTimeout = Timeout; + + byte[] bytes = listener.Receive(ref groupEP); + string message = Encoding.UTF8.GetString(bytes, 0, bytes.Length); + + foundSomething = true; + if (!knownServer.Contains(groupEP.Address.ToString())) + { + knownServer.Add(groupEP.Address.ToString()); + if (_OnDiscovered != null) + { + IPHostEntry e = Dns.GetHostEntry(groupEP.Address); + string hostname = e.HostName; + + _OnDiscovered(groupEP.Address.ToString(), hostname); + } + } + + listener.Close(); + } + catch (Exception) + { + if (listener != null) + listener.Close(); + } + } + _DiscoverRunning = false; + + if (!foundSomething) + _OnDiscovered("Timeout", "unknown"); + } + } +} diff --git a/ClientServerLib/ClientServerLib/ClientServerLib.csproj b/ClientServerLib/ClientServerLib/ClientServerLib.csproj index d5bd8b7e..fbda0800 100644 --- a/ClientServerLib/ClientServerLib/ClientServerLib.csproj +++ b/ClientServerLib/ClientServerLib/ClientServerLib.csproj @@ -46,6 +46,7 @@ + diff --git a/ClientServerLib/ClientServerLib/Vocaluxe/CCommands.cs b/ClientServerLib/ClientServerLib/Vocaluxe/CCommands.cs index ff9f518b..ecfa087e 100644 --- a/ClientServerLib/ClientServerLib/Vocaluxe/CCommands.cs +++ b/ClientServerLib/ClientServerLib/Vocaluxe/CCommands.cs @@ -14,6 +14,8 @@ namespace Vocaluxe.Base.Server private static UTF8Encoding encoder = new UTF8Encoding(); public static SHA256Managed SHA256 = new SHA256Managed(); + public const string BroadcastKeyword = "I am a Vocaluxe Server"; + #region Commands public const int ResponseOK = 1; public const int ResponseNOK = 2; diff --git a/ClientServerLib/ClientTest/ClientTest.Designer.cs b/ClientServerLib/ClientTest/ClientTest.Designer.cs index 65d2f867..33b815d3 100644 --- a/ClientServerLib/ClientTest/ClientTest.Designer.cs +++ b/ClientServerLib/ClientTest/ClientTest.Designer.cs @@ -49,6 +49,9 @@ this.btDown = new System.Windows.Forms.Button(); this.btSendAvatar = new System.Windows.Forms.Button(); this.btSendProfile = new System.Windows.Forms.Button(); + this.btDiscover = new System.Windows.Forms.Button(); + this.tbDiscoveredServer = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); this.statusStrip1.SuspendLayout(); this.SuspendLayout(); // @@ -251,11 +254,44 @@ this.btSendProfile.UseVisualStyleBackColor = true; this.btSendProfile.Click += new System.EventHandler(this.btSendProfile_Click); // + // btDiscover + // + this.btDiscover.Location = new System.Drawing.Point(831, 502); + this.btDiscover.Name = "btDiscover"; + this.btDiscover.Size = new System.Drawing.Size(165, 23); + this.btDiscover.TabIndex = 16; + this.btDiscover.Text = "Discover"; + this.btDiscover.UseVisualStyleBackColor = true; + this.btDiscover.Click += new System.EventHandler(this.btDiscover_Click); + // + // tbDiscoveredServer + // + this.tbDiscoveredServer.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbDiscoveredServer.Location = new System.Drawing.Point(15, 405); + this.tbDiscoveredServer.Multiline = true; + this.tbDiscoveredServer.Name = "tbDiscoveredServer"; + this.tbDiscoveredServer.Size = new System.Drawing.Size(810, 120); + this.tbDiscoveredServer.TabIndex = 17; + this.tbDiscoveredServer.WordWrap = false; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(12, 389); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(41, 13); + this.label1.TabIndex = 18; + this.label1.Text = "Server:"; + // // ClientTest // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(1008, 550); + this.Controls.Add(this.label1); + this.Controls.Add(this.tbDiscoveredServer); + this.Controls.Add(this.btDiscover); this.Controls.Add(this.btSendProfile); this.Controls.Add(this.btSendAvatar); this.Controls.Add(this.btDown); @@ -307,6 +343,9 @@ private System.Windows.Forms.Button btDown; private System.Windows.Forms.Button btSendAvatar; private System.Windows.Forms.Button btSendProfile; + private System.Windows.Forms.Button btDiscover; + private System.Windows.Forms.TextBox tbDiscoveredServer; + private System.Windows.Forms.Label label1; } } diff --git a/ClientServerLib/ClientTest/ClientTest.cs b/ClientServerLib/ClientTest/ClientTest.cs index f8c4a60d..af0be5b5 100644 --- a/ClientServerLib/ClientTest/ClientTest.cs +++ b/ClientServerLib/ClientTest/ClientTest.cs @@ -19,12 +19,15 @@ namespace ClientTest public partial class ClientTest : Form { CClient client; + CDiscover discover; + private bool loggedIn; public ClientTest() { client = new CClient(); loggedIn = false; + discover = new CDiscover(3000, CCommands.BroadcastKeyword); InitializeComponent(); } @@ -32,6 +35,7 @@ namespace ClientTest protected override void OnClosing(CancelEventArgs e) { client.Close(); + discover.Stop(); base.OnClosing(e); } @@ -262,5 +266,22 @@ namespace ClientTest client.SendMessage(CCommands.CreateCommandSendProfile(data, "TestUser", 0), OnResponse); } } + + private void btDiscover_Click(object sender, EventArgs e) + { + tbDiscoveredServer.Text = "Searching for Vocaluxe Server:\r\n"; + discover.Discover(_OnDiscovered); + } + + private void _OnDiscovered(string Address, string HostName) + { + this.Invoke((MethodInvoker)delegate + { + if (Address != "Timeout") + tbDiscoveredServer.Text += "IP = " + Address + "; HostName = " + HostName + "\r\n"; + else + tbDiscoveredServer.Text += "Timeout" + "\r\n"; + }); + } } } diff --git a/Output/ClientServerLib.dll b/Output/ClientServerLib.dll index f59ca7e80a13724573c26de71561250c67742c92..78c652b3c227f3753e7253d9cc2a3186fca85ca7 100644 GIT binary patch literal 43520 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 literal 41472 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 diff --git a/Vocaluxe/Base/Server/CVocaluxeServer.cs b/Vocaluxe/Base/Server/CVocaluxeServer.cs index f82f81b5..78f7d189 100644 --- a/Vocaluxe/Base/Server/CVocaluxeServer.cs +++ b/Vocaluxe/Base/Server/CVocaluxeServer.cs @@ -19,6 +19,7 @@ namespace Vocaluxe.Base.Server static class CVocaluxeServer { private static CServer _Server; + private static CDiscover _Discover; private static Dictionary _Clients; public static CControllerFramework Controller = new CControllerFramework(); @@ -27,18 +28,23 @@ namespace Vocaluxe.Base.Server { _Clients = new Dictionary(); _Server = new CServer(RequestHandler, CConfig.ServerPort, CConfig.ServerEncryption == EOffOn.TR_CONFIG_ON); + _Discover = new CDiscover(CConfig.ServerPort, CCommands.ResponseKeyword); Controller.Init(); } public static void Start() { if (CConfig.ServerActive == EOffOn.TR_CONFIG_ON) + { _Server.Start(); + _Discover.StartBroadcasting(); + } } public static void Close() { _Server.Stop(); + _Discover.Stop(); _Clients = new Dictionary(); }