Search Unity

  1. We are migrating the Unity Forums to Unity Discussions. On July 12, the Unity Forums will become read-only.

    Please, do not make any changes to your username or email addresses at id.unity.com during this transition time.

    It's still possible to reply to existing private message conversations during the migration, but any new replies you post will be missing after the main migration is complete. We'll do our best to migrate these messages in a follow-up step.

    On July 15, Unity Discussions will become read-only until July 18, when the new design and the migrated forum contents will go live.


    Read our full announcement for more information and let us know if you have any questions.

C# Detecting Connected Devices through Lan

Discussion in 'Multiplayer' started by Sbizz, Feb 10, 2015.

  1. Sbizz

    Sbizz

    Joined:
    Oct 2, 2014
    Posts:
    250
    Hello there.

    For some tests, I need to be able to connect from a device (= android/ios) to another (= android/ios) without Internet ; basically, a device will active his hotspot wifi and the other ones will connect to this hotspot. I need these phones to be able to detect the others (and also find a server but for now, I just want them to see all devices on their local network).

    To do that, I use the C# class "Ping". But apparently, I do it wrong 'cause it just doesn't work :p I just try to send a ping on 255.255.255.255 to see if, at least, one device send me a pong..

    Here is my (entire) code :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Text;
    5. using System.Net;
    6. using System.Net.Sockets;
    7. using System.Net.NetworkInformation;
    8.  
    9. public class LanManager {
    10.     public List<KeyValuePair<string, int>> _addresses { get; private set; }
    11.  
    12.     // Addresse that the ping will reach
    13.     public string addressToBroadcast = "255.255.255.255";
    14.  
    15.     public int timeout = 1000;
    16.  
    17.     public LanManager() {
    18.         _addresses = new List<KeyValuePair<string,int>>();
    19.     }
    20.  
    21.     public void SendPing() {
    22.         _addresses.Clear();
    23.  
    24.         System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
    25.  
    26.         // 128 TTL and DontFragment
    27.         PingOptions pingOption = new PingOptions(128, true);
    28.  
    29.         // Once the ping has reached his target (or has timed out), call this function
    30.         ping.PingCompleted += ping_PingCompleted;
    31.  
    32.         byte[] buffer = Encoding.ASCII.GetBytes("ping");
    33.  
    34.         // Do not block the main thread
    35.         ping.SendAsync(addressToBroadcast, timeout, buffer, pingOption, addressToBroadcast);
    36.     }
    37.  
    38.  
    39.     private void ping_PingCompleted(object sender, PingCompletedEventArgs e) {
    40.         string address = (string)e.UserState;
    41.  
    42.         // For debug purpose
    43.         _addresses.Add(new KeyValuePair<string, int>("127.0.0.1", 26000));
    44.  
    45.         if (e.Cancelled) {
    46.             Debug.Log("Ping Canceled!");
    47.         }
    48.    
    49.         if (e.Error != null) {
    50.             Debug.Log(e.Error);
    51.         }
    52.    
    53.         displayReply(e.Reply);
    54.     }
    55.  
    56.     private void displayReply(PingReply reply) {
    57.         if (reply != null) {
    58.             if (reply.Status == IPStatus.Success) {
    59.                 Debug.Log("Pong from " + reply.Address);
    60.             }
    61.         } else {
    62.             Debug.Log("No reply");
    63.         }
    64.     }
    65. }
    66.  
    I know I'm doing something wrong about the address, because if I set a real address (like 192.168.1.48, which his my address or even if I set the printer's address), I get a pong. But I need to be able to detect any devices on the current local network.

    PS: I don't want to use a Master Server !! The purpose of this is to be able to play a game without any connection and on a mobile phone (which will not start a Master Server).

    Thank you !
    Sbizz.
     
    dimaveschikov likes this.
  2. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Hi there! We actually just implemented LAN Discovery in our networking system.

    What you are wanting to do is not to send a message to 255.255.255.255 but you want to send it to the internal ip location and net mask. So if the ip addresses are formated like: 192.168.0.8 then you want to do 192.168.0.255. This will broadcast the message to that net mask. You will find documentation on line about 255.255.255.255 but when you try it you may find that it doesn't work for all machines. What we do internally is that we retrieve the internal ip address of the machine and then we remove the last byte of the address to make it look something like 192.168.0. and then we append with 255. That way if the network is formatted as 192.168.1.x or 10.0.0.x then we are covered there as well.

    Also a side note, IPv6 doesn't seem to have this awesome broadcasting, probably because the massive number range; but all in all, that is not a problem because I don't see internal networks using IPv6 anytime soon.
     
    d1favero likes this.
  3. Sbizz

    Sbizz

    Joined:
    Oct 2, 2014
    Posts:
    250
    Thank you @farrisarts for your answer !

    Yesterday I read an article on what you said, so I tried something else :

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Text;
    5. using System.Net;
    6. using System.Net.Sockets;
    7. using System.Net.NetworkInformation;
    8.  
    9. public class LanManager {
    10.     public List<string> _addresses { get; private set; }
    11.  
    12.     // Addresse that the ping will reach
    13.     [HideInInspector] public string addressToBroadcast = "192.168.1.";
    14.  
    15.     public int timeout = 10;
    16.  
    17.     public bool _isSearching { get; private set; }
    18.     public float _percentSearching { get; private set; }
    19.    
    20.     public int _portServer { get; private set; }
    21.  
    22.     public LanManager() {
    23.         _addresses = new List<string>();
    24.     }
    25.  
    26.     public IEnumerator ScanNetworkInterfaces() {
    27.         foreach(NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
    28.         {
    29.                if(ni.OperationalStatus==OperationalStatus.Up) {
    30.                 if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet) {
    31.                        foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses) {
    32.                            if (ip != null && ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
    33.                            {
    34.                             // My addresses
    35.                            }
    36.                    
    37.                         yield return null;
    38.                     }
    39.                    }
    40.             }
    41.  
    42.             yield return null;
    43.         }
    44.     }
    45.  
    46.     public IEnumerator SendRangePing(bool bClear = true) {
    47.         if (bClear) {
    48.             _addresses.Clear();
    49.         }
    50.  
    51.         _isSearching = true;
    52.         for (int i = 0 ; i < 255 ; i++) {
    53.             string address = addressToBroadcast + i;
    54.  
    55.             SendPing(address);
    56.  
    57.             _percentSearching = (float)i / 255;
    58.  
    59.             yield return null;
    60.         }
    61.         _isSearching = false;
    62.     }
    63.  
    64.     public void SendPing(string address) {
    65.         System.Net.NetworkInformation.Ping ping = new System.Net.NetworkInformation.Ping();
    66.  
    67.         // 128 TTL and DontFragment
    68.         PingOptions pingOption = new PingOptions(16, true);
    69.  
    70.         // Once the ping has reached his target (or has timed out), call this function
    71.         ping.PingCompleted += ping_PingCompleted;
    72.  
    73.         byte[] buffer = Encoding.ASCII.GetBytes("ping");
    74.  
    75.         try {
    76.             // Do not block the main thread
    77.             //ping.SendAsync(address, timeout, buffer, pingOption, addressToBroadcast);
    78.             PingReply reply = ping.Send(address, timeout, buffer, pingOption);
    79.  
    80.             Debug.Log("Ping Sent at " + address);
    81.  
    82.             displayReply(reply);
    83.         } catch (PingException ex) {
    84.             Debug.Log(string.Format("Connection Error: {0}", ex.Message));
    85.         } catch (SocketException ex) {
    86.             Debug.Log(string.Format("Connection Error: {0}", ex.Message));
    87.         }
    88.     }
    89.  
    90.  
    91.     private void ping_PingCompleted(object sender, PingCompletedEventArgs e) {
    92.         string address = (string)e.UserState;
    93.  
    94.         if (e.Cancelled) {
    95.             Debug.Log("Ping Canceled!");
    96.         }
    97.        
    98.         if (e.Error != null) {
    99.             Debug.Log(e.Error);
    100.         }
    101.        
    102.         displayReply(e.Reply);
    103.     }
    104.  
    105.     private void displayReply(PingReply reply) {
    106.         if (reply != null) {
    107.             Debug.Log("Status: " + reply.Status);
    108.             if (reply.Status == IPStatus.Success) {
    109.                 Debug.Log("Pong from " + reply.Address);
    110.                 _addresses.Add(reply.Address.ToString());
    111.  
    112.                 if (NetworkManager.OnAddressFound != null) {
    113.                     NetworkManager.OnAddressFound();
    114.                 }
    115.             }
    116.         } else {
    117.             Debug.Log("No reply");
    118.         }
    119.     }
    120. }
    121.  
    Basically, I have 3 main functions :
    ScanNetworkInterfaces : it will be used to know the current device's address,
    SendRangePing : it was just a test,
    SendPing : send a ping at one specific address.

    I tried to send a ping at 192.168.1.255 :

    Code (CSharp):
    1. lanManager.SendPing("192.168.1.255");
    Of course, I checked my local addresses ; my computer's address is 192.168.1.48 and my phones 192.168.1.30 and 192.168.1.24 (they are on the same Wi-Fi).

    And the status of the ping is "TimedOut". I tried with a higher timeout (12000).

    I also tried with SendRangePing (so it uses SendPing to send ping from 192.168.1.0 to 192.168.1.255) : it seems to work because I receive several responses ; but it's really weird because I detect my own computer, my phone N°1 but not the second one :

    reseau.jpg

    Maybe I need to configure something on the network ?
     
  4. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Interesting. It could be something that is a part of the ping libraries (though I would imagine it is doing roughly the same thing). It works for us, however we do not use ping, we create a socket and then do a ping to all found local ip ranges. This seems to work for us:

    Code (CSharp):
    1.  
    2. foreach (System.Net.NetworkInformation.NetworkInterface f in System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces())
    3. {
    4.    if (f.OperationalStatus == System.Net.NetworkInformation.OperationalStatus.Up)
    5.    {
    6.      foreach (System.Net.NetworkInformation.GatewayIPAddressInformation d in f.GetIPProperties().GatewayAddresses)
    7.      {
    8.        if (d.Address.ToString() == "0.0.0.0") continue;
    9.  
    10.        if (d.Address.ToString().Contains("."))
    11.          localSubNet.Add(d.Address.ToString().Remove(d.Address.ToString().LastIndexOf('.')));
    12.      }
    13.    }
    14. }
    15.  
    16. foreach (string s in localSubNet)
    17.    Client.Send(new byte[1], 1, new IPEndPoint(IPAddress.Parse(s + ".255"), port));
    18.  
    19.  
     
  5. Sbizz

    Sbizz

    Joined:
    Oct 2, 2014
    Posts:
    250
    Hmm. Okay, I tried to avoid using sockets, because when I found this class, "Ping", I told myself that was something genius.

    Nope.

    I'll come back later and tell you if I figure out the issue ;) Thank you again !
     
  6. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    Alright, awesome! Let me know! :D. If not I can probably build up a sample or something. One that works on our local network :)
     
  7. Sbizz

    Sbizz

    Joined:
    Oct 2, 2014
    Posts:
    250
    So, still working on this ... system. It pisses me off :mad:

    - Did you try your code on mobile devices ? Because I can't get network interfaces when I launched my little test on a mobile phone (android). It is not a real problem, I guess. Most of my tests are on Windows.

    - Here is my new code, I checked on internet several tutorials and tried to get all useful data to create a socket that sends a ping and retrieve the data from a pong :

    Code (CSharp):
    1.     public void SendMessages(int port) {
    2.         if (_socket == null) {
    3.             _socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    4.  
    5.             if (_socket == null) {
    6.                 Debug.LogWarning("Socket creation failed");
    7.                 return ;
    8.             }
    9.  
    10.             _socket.EnableBroadcast = true;
    11.             _socket.ReceiveTimeout = timeout;
    12.             _socket.DontFragment = true;
    13.  
    14.             _destinationEndPoint = new IPEndPoint(IPAddress.Broadcast, port);
    15.             _remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
    16.  
    17.             byte[] str = Encoding.ASCII.GetBytes("ping");
    18.  
    19.             _socket.SendTo(str, _destinationEndPoint);
    20.  
    21.             _socket.BeginReceiveFrom(new byte[1024], 0, 1024, SocketFlags.None,
    22.                                      ref _remoteEndPoint, new AsyncCallback(_OperatorCallBack), null);
    23.         }
    24.     }
    25.  
    26.     private void _OperatorCallBack(IAsyncResult ar) {
    27.         try {
    28.             int size = _socket.EndReceiveFrom(ar, ref _remoteEndPoint);
    29.  
    30.             _addresses.Add(_remoteEndPoint.ToString());
    31.             Debug.Log(_remoteEndPoint);
    32.  
    33.             //_socket.BeginReceiveFrom(new byte[1024], 0, 1024, SocketFlags.None,
    34.             //                         ref _castResponseEndPoint, new AsyncCallback(_OperatorCallBack), null);
    35.         } catch (Exception exp) {
    36.             Debug.Log(exp.ToString());
    37.         }
    38.     }
    I tried several ways to do it, but I just can't. I must do something really stupid, because all the tutorials do as I do (I mean... I do as THEY do :p). I even tried RAW sockets (ICMP) etc. It just doesn't work.

    Should I do something from the server side ? I mean, I just launch a server by using this function

    Code (CSharp):
    1. Network.InitializeServer(maxConnections, portServer, !Network.HavePublicAddress());
    (port = 26000)

    I'm gonna kill myself.
     
  8. Brent_Farris

    Brent_Farris

    Joined:
    Jul 13, 2012
    Posts:
    881
    We did our tests on Mac and Windows but haven't tried mobile yet. The one I suggested is a cleaner way (at least on windows) to get the internal IP for the machine, however there is another method that doesn't use the way I showed. If the way that I mentioned doesn't work on mobile (will be doing tests on it now) then we will implement the following:

    Code (CSharp):
    1. public string LocalIPAddress()
    2. {
    3.     IPHostEntry host;
    4.     List<string> foundLocals = new List<string>();
    5.  
    6.     host = Dns.GetHostEntry(Dns.GetHostName());
    7.     foreach (IPAddress ip in host.AddressList)
    8.     {
    9.         if (ip.AddressFamily == AddressFamily.InterNetwork)
    10.             foundLocals.add(ip.ToString());
    11.     }
    12.  
    13.     return localIP;
    14. }
    15.  
    16. foreach (string s in localSubNet)
    17.     Client.Send(new byte[1], 1, new IPEndPoint(IPAddress.Parse(s + ".255"), [URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=port']port[/URL]));
    18.  
    NOTE: I would probably need to check for IPv6 in this one

    Ah! For my implementation, since I wrote the whole networking system, I used my own custom sockets for server/client. I haven't actually tried my suggestion for Unity sockets, though I would imagine that they work the same...
     
  9. Sbizz

    Sbizz

    Joined:
    Oct 2, 2014
    Posts:
    250
    Hi @farrisarts

    So I changed some stuff in my code and now it works.

    So as I thought, you'll have to use Dns.GetHostEntry() if you want to detect the local addresses of a mobile device.

    But I still have a problem: I use "SendTo" to send a ping and it appears that on a mobile device, it just.. does nothing. Worst: it does an infinite loop.

    On a computer, it works perfectly and I can detect a server on any device on the current network.
     
  10. Sbizz

    Sbizz

    Joined:
    Oct 2, 2014
    Posts:
    250
    Okayyyy! I figured out what was the problem.

    I don't know why it did work on my computer, but I forgot to use SetSocketOption (in Broadcast mode).

    If someone wants the code:

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using System.Text;
    6. using System.Net;
    7. using System.Net.Sockets;
    8. using System.Net.NetworkInformation;
    9.  
    10. public class LanManager {
    11.     // Addresses of the computer (Ethernet, WiFi, etc.)
    12.     public List<string> _localAddresses { get; private set; }
    13.     public List<string> _localSubAddresses { get; private set; }
    14.  
    15.     // Addresses found on the network with a server launched
    16.     public List<string> _addresses { get; private set; }
    17.  
    18.     public bool _isSearching { get; private set; }
    19.     public float _percentSearching { get; private set; }
    20.    
    21.     private Socket _socketServer;
    22.     private Socket _socketClient;
    23.  
    24.     private EndPoint _remoteEndPoint;
    25.  
    26.     public LanManager() {
    27.         _addresses = new List<string>();
    28.         _localAddresses = new List<string>();
    29.         _localSubAddresses = new List<string>();
    30.     }
    31.  
    32.     public void StartServer(int port) {
    33.         if (_socketServer == null && _socketClient == null) {
    34.             try {
    35.                 _socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    36.  
    37.                 if (_socketServer == null) {
    38.                     Debug.LogWarning("SocketServer creation failed");
    39.                     return;
    40.                 }
    41.  
    42.                 // Check if we received pings
    43.                 _socketServer.Bind(new IPEndPoint(IPAddress.Any, port));
    44.  
    45.                 _remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
    46.  
    47.                 _socketServer.BeginReceiveFrom(new byte[1024], 0, 1024, SocketFlags.None,
    48.                                                ref _remoteEndPoint, new AsyncCallback(_ReceiveServer), null);
    49.             } catch (Exception ex) {
    50.                 Debug.Log(ex.Message);
    51.             }
    52.         }
    53.     }
    54.  
    55.     public void CloseServer() {
    56.         if (_socketServer != null) {
    57.             _socketServer.Close();
    58.             _socketServer = null;
    59.         }
    60.     }
    61.  
    62.     public void StartClient(int port) {
    63.         if (_socketServer == null && _socketClient == null) {
    64.             try {
    65.                 _socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
    66.  
    67.                 if (_socketClient == null) {
    68.                     Debug.LogWarning("SocketClient creation failed");
    69.                     return;
    70.                 }
    71.  
    72.                 // Check if we received response from a remote (server)
    73.                 _socketClient.Bind(new IPEndPoint(IPAddress.Any, port));
    74.  
    75.                 _socketClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
    76.                 _socketClient.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
    77.  
    78.                 _remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
    79.  
    80.                 _socketClient.BeginReceiveFrom(new byte[1024], 0, 1024, SocketFlags.None,
    81.                                          ref _remoteEndPoint, new AsyncCallback(_ReceiveClient), null);
    82.             } catch (Exception ex) {
    83.                 Debug.Log(ex.Message);
    84.             }
    85.         }
    86.     }
    87.  
    88.     public void CloseClient() {
    89.         if (_socketClient != null) {
    90.             _socketClient.Close();
    91.             _socketClient = null;
    92.         }
    93.     }
    94.  
    95.     public IEnumerator SendPing(int port) {
    96.         _addresses.Clear();
    97.  
    98.         if (_socketClient != null) {
    99.             int maxSend = 4;
    100.             float countMax = (maxSend * _localSubAddresses.Count) - 1;
    101.  
    102.             float index = 0;
    103.  
    104.             _isSearching = true;
    105.  
    106.             // Send several pings just to be sure (a ping can be lost!)
    107.             for (int i = 0 ; i < maxSend ; i++) {
    108.  
    109.                 // For each address that this device has
    110.                 foreach (string subAddress in _localSubAddresses) {
    111.                     IPEndPoint destinationEndPoint = new IPEndPoint(IPAddress.Parse(subAddress + ".255"), port);
    112.                     byte[] str = Encoding.ASCII.GetBytes("ping");
    113.  
    114.                     _socketClient.SendTo(str, destinationEndPoint);
    115.  
    116.                     _percentSearching = index / countMax;
    117.  
    118.                     index++;
    119.  
    120.                     yield return new WaitForSeconds(0.1f);
    121.                 }
    122.             }
    123.             _isSearching = false;
    124.         }
    125.     }
    126.  
    127.     private void _ReceiveServer(IAsyncResult ar) {
    128.         if (_socketServer != null) {
    129.             try {
    130.                 int size = _socketServer.EndReceiveFrom(ar, ref _remoteEndPoint);
    131.                 byte[] str = Encoding.ASCII.GetBytes("pong");
    132.  
    133.                 // Send a pong to the remote (client)
    134.                 _socketServer.SendTo(str, _remoteEndPoint);
    135.  
    136.                 _socketServer.BeginReceiveFrom(new byte[1024], 0, 1024, SocketFlags.None,
    137.                                                ref _remoteEndPoint, new AsyncCallback(_ReceiveServer), null);
    138.             } catch (Exception ex) {
    139.                 Debug.Log(ex.ToString());
    140.             }
    141.         }
    142.     }
    143.  
    144.     private void _ReceiveClient(IAsyncResult ar) {
    145.         if (_socketClient != null) {
    146.             try {
    147.                 int size = _socketClient.EndReceiveFrom(ar, ref _remoteEndPoint);
    148.                 string address = _remoteEndPoint.ToString().Split(':')[0];
    149.  
    150.                 // This is no ourself and we do not already have this address
    151.                 if (!_localAddresses.Contains(address) && !_addresses.Contains(address)) {
    152.                     _addresses.Add(address);
    153.                 }
    154.  
    155.                 _socketClient.BeginReceiveFrom(new byte[1024], 0, 1024, SocketFlags.None,
    156.                                                ref _remoteEndPoint, new AsyncCallback(_ReceiveClient), null);
    157.             } catch (Exception ex) {
    158.                 Debug.Log(ex.ToString());
    159.             }
    160.         }
    161.     }
    162.  
    163.     public void ScanHost() {
    164.         IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
    165.  
    166.         foreach (IPAddress ip in host.AddressList) {
    167.             if (ip.AddressFamily == AddressFamily.InterNetwork) {
    168.                 string address = ip.ToString();
    169.                 string subAddress = address.Remove(address.LastIndexOf('.'));
    170.  
    171.                 _localAddresses.Add(address);
    172.  
    173.                 if (!_localSubAddresses.Contains(subAddress)) {
    174.                     _localSubAddresses.Add(subAddress);
    175.                 }
    176.             }
    177.         }
    178.     }
    179. }
    180.  
     
  11. Erdrako

    Erdrako

    Joined:
    Jul 1, 2016
    Posts:
    4
    Hi! I was reading the code and right now im trying to do exactly the same... so far i copied some code from a tutorial as reference and then modified it to scan the subnet...
    the example is actually running on a winforms project as im testing it before moving it to an implementable script on unity... i have to say that im a noob coding, and also i had 0 network knowledge prior the last 2 weeks which i've been searching over and over to find a way to implement a LAN matchmaker for my unity project..
    The problem im having with this is the same you had... i only get response from pcs...
    From any other device i get a timeout... and i still havent managed to figure out how to make the "ping-pong" from one end to another... I just read your code but i dont get when you use the "sendPing()", is it from client or from server? or maybe both?

    Here is my little (seemingly functional) abomination xD :

    Code (CSharp):
    1.  
    2. using System.Threading.Tasks;
    3. using System.Windows.Forms;
    4. using System.Net;
    5. using System.Net.Sockets;
    6. using System.Net.NetworkInformation;
    7. using System.Threading;
    8. using Microsoft.VisualBasic;
    9.  
    10.  
    11. namespace SubnetScanner
    12. {
    13.     public partial class Form1 : Form
    14.     {
    15.         public Form1()
    16.         {
    17.             InitializeComponent();
    18.             Control.CheckForIllegalCrossThreadCalls = false;
    19.         }
    20.         Thread myThread = null;
    21.         Thread myThread2 = null;
    22.         int tasks = 0;
    23.         string[] aliveaddres = new string[300];
    24.         public void scan(string subnet)
    25.         {
    26.             Ping myPing;
    27.             PingReply reply;
    28.             IPAddress addr;
    29.             IPHostEntry host;
    30.        
    31.        
    32.        
    33.             for(int i = 1; i <= 255; i ++)
    34.             {
    35.                 int ai = i;
    36.                 Task.Factory.StartNew(()=>
    37.                 {
    38.                     try
    39.                     {
    40.                         myPing = new Ping();
    41.                         reply = myPing.Send(subnet + "." + ai.ToString(), 2000);
    42.                    
    43.                         if (reply.Status == IPStatus.Success)
    44.                         {
    45.                             try
    46.                             {
    47.                                 addr = IPAddress.Parse(subnet + "." + ai.ToString());
    48.                                 host = Dns.GetHostEntry(addr);
    49.                                 tasks++;
    50.  
    51.                                     aliveaddres[ai] = subnet + "." + ai.ToString() + " - " + host.HostName.ToString()+" (" + reply.Status + ", " + reply.RoundtripTime +","+reply.Address+ ")";
    52.                                 return;
    53.                             }
    54.                             catch { tasks++; aliveaddres[ai] = subnet + "." + ai.ToString() + " - Down (" + reply.Status+","+reply.RoundtripTime+ "," + reply.Address + ")" ; return; }
    55.                         }
    56.                         else
    57.                         {
    58.                             tasks++; aliveaddres[ai] = subnet + "." + ai.ToString() + " - Unreachable (" + reply.Status + "," + reply.RoundtripTime + "," + reply.Address + ")"; return;
    59.                         }
    60.                     }
    61.                     catch { tasks++; aliveaddres[ai] = subnet + "." + ai.ToString() + " - Error Detected"; return; }
    62.                 },TaskCreationOptions.PreferFairness|TaskCreationOptions.LongRunning);
    63.             }
    64.             return;
    65.         }
    66.  
    67.         /*initialize scan */private void button1_Click(object sender, System.EventArgs e)
    68.         {
    69.        
    70.        
    71.             string ip = GetIp();
    72.             int sub = Strings.InStr(Strings.InStr(Strings.InStr(1, GetIp(), ".", CompareMethod.Text) + 1,ip,".",CompareMethod.Text)+1,ip,".",CompareMethod.Text)-1;
    73.             tasks = 0;
    74.             System.Array.Clear(aliveaddres, 0, aliveaddres.Length);
    75.             listBox2.Items.Clear();
    76.             listBox1.Items.Clear();
    77.             myThread = new Thread(() => scan(Strings.Mid(ip, 1, sub)));
    78.             myThread.Start();
    79.             myThread2 = new Thread(() => checkForScanEnd());
    80.             myThread2.Start();
    81.             if (myThread.IsAlive)
    82.             {
    83.                 button2.Enabled = true;
    84.                 button1.Enabled = false;
    85.                 textBox1.Enabled = false;
    86.             }
    87.  
    88.         }
    89.  
    90.  
    91.         private void checkForScanEnd()
    92.         {
    93.             int timar = 0;
    94.             int timeoutt = 6000;
    95.             while(tasks < 255 && timar < timeoutt)
    96.             {
    97.                 Thread.Sleep(1);
    98.                 timar++;
    99.             }
    100.             if(aliveaddres.Length >= 255)
    101.             {
    102.                 stopThread(myThread);
    103.                 listBox1.Items.Add("Scan Complete");
    104.                 listBox1.SelectedIndex = listBox1.Items.Count - 1;
    105.            
    106.                 int registeredips = 0;
    107.                 for(int ai = 1; ai < aliveaddres.Length; ai++)
    108.                 {
    109.                     if(aliveaddres[ai] != null)
    110.                     {
    111.                         listBox2.Items.Add(aliveaddres[ai]);
    112.                         registeredips ++;
    113.                     }
    114.                    
    115.  
    116.                 }
    117.                 label1.Text = tasks.ToString();
    118.                 label2.Text = registeredips.ToString();
    119.                 return;
    120.             }
    121.             if(aliveaddres.Length < 255 && timar >= timeoutt)
    122.             {
    123.                 stopThread(myThread);
    124.                 listBox1.Items.Add("Scan Completed by timeout");
    125.                 listBox1.SelectedIndex = listBox1.Items.Count - 1;
    126.                 listBox1.SelectedIndex = listBox1.Items.Count - 1;
    127.                 return;
    128.             }
    129.         }
    130.  
    131.         /*Cancel*/ private void button2_Click(object sender, System.EventArgs e)
    132.         {
    133.             stopThread(myThread);
    134.             stopThread(myThread2);
    135.         }
    136.  
    137.         private string GetIp()
    138.         {
    139.             IPHostEntry host;
    140.             host = Dns.GetHostEntry(Dns.GetHostName());
    141.             foreach (IPAddress ip in host.AddressList)
    142.             {
    143.                 if (ip.AddressFamily == AddressFamily.InterNetwork)
    144.                 {
    145.                     return ip.ToString();
    146.                 }
    147.             }
    148.             return "127.0.0.1";
    149.         }
    150.  
    151.         private void stopThread(Thread kill)
    152.         {
    153.             kill.Abort();
    154.             button2.Enabled = false;
    155.             button1.Enabled = true;
    156.             textBox1.Enabled = false;
    157.         }
    158.  
    159.  
    160.     }
    161.  
    162. }
    163.  
    I would like to, somehow, mix both codes and successfully implement it on an unity project; i was thinking on a way to mix the code i was working on with Unet, passing an string array with the "ponged" addresses setting the properties .. right know i honestly feel kind of lost and would REALLY APPRECIATE!! some guidance...

    some background info :

    All the programming i know, i learned it on my own, and for me, in this particular case, i think i need someone to guide me a little bit, and well... honestly dont have other place to look for that guidance...
    Thanks in advance to any kind soul who lends me a hand in this epic trouble im facing (at least epic for me lol).

    Heres is a ss from the winform:

    screendesubnetscanner.PNG

    as you can see .1 is the router .2 is an unknown device (probably a mobile), .8 is a printer, and .21 is my mobile.

    P.D: please excuse my english... its not my native language..
     
  12. JesusChrist17

    JesusChrist17

    Joined:
    Sep 17, 2016
    Posts:
    12
    does anybody know how can i get the list of lan conections using network discovery?, i can see using the ui by default, but i want to build my onw interface but i dont know how to get this data. Thanks