如何在运行我的程序的本地网络上获取主机的IP地址

001*_*014 2 c# sockets port p2p tcp

我已经构建了一个对等的C#视频会议应用程序,它使用特定的TCP端口(17500)进行音频通信.目前,在我的应用程序界面上,我输入了另一个打开程序以进行通信的IP地址.我想要做的是自动找到IP地址.

所以,我认为实现这一目标的最佳方法是获取使用相同TCP端口号17500的本地IP地址.我该怎么做?或者是否有任何其他方法使用相同的应用程序获取IP地址?

Ese*_*ser 6

如评论中所述,您需要某种对等发现协议.

由于许多多媒体设备,路由器等使用基于多播的发现协议(如SSDP),因此我创建了类似的发现服务示例.

用法很简单.只是用

Discoverer.PeerJoined = ip => Console.WriteLine("JOINED:" + ip);
Discoverer.PeerLeft= ip => Console.WriteLine("LEFT:" + ip);

Discoverer.Start();
Run Code Online (Sandbox Code Playgroud)

您的所有客户都将使用相同的代码.


using System;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Caching; // add this library from the reference tab
using System.Text;
using System.Threading.Tasks;

namespace SO
{
    public class Discoverer
    {
        static string MULTICAST_IP = "238.212.223.50"; //Random between 224.X.X.X - 239.X.X.X
        static int MULTICAST_PORT = 2015;    //Random

        static UdpClient _UdpClient;
        static MemoryCache _Peers = new MemoryCache("_PEERS_");

        public static Action<string> PeerJoined = null;
        public static Action<string> PeerLeft = null;

        public static void Start()
        {
            _UdpClient = new UdpClient();
            _UdpClient.Client.Bind(new IPEndPoint(IPAddress.Any, MULTICAST_PORT));
            _UdpClient.JoinMulticastGroup(IPAddress.Parse(MULTICAST_IP));


            Task.Run(() => Receiver());
            Task.Run(() => Sender());
        }

        static void Sender()
        {
            var IamHere = Encoding.UTF8.GetBytes("I AM ALIVE");
            IPEndPoint mcastEndPoint = new IPEndPoint(IPAddress.Parse(MULTICAST_IP), MULTICAST_PORT);

            while (true)
            {
                _UdpClient.Send(IamHere, IamHere.Length, mcastEndPoint);
                Task.Delay(1000).Wait();
            }
        }

        static void Receiver()
        {
            var from = new IPEndPoint(0, 0);
            while (true)
            {
                _UdpClient.Receive(ref from);
                if (_Peers.Add(new CacheItem(from.Address.ToString(), from),
                               new CacheItemPolicy() { 
                                    SlidingExpiration = TimeSpan.FromSeconds(20),
                                    RemovedCallback = (x) => { if (PeerLeft != null) PeerLeft(x.CacheItem.Key); }
                               }
                             )
                )
                {
                    if (PeerJoined != null) PeerJoined(from.Address.ToString());
                }

                Console.WriteLine(from.Address.ToString());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在关于算法的一点点:

  • 每个客户端每秒多播一个数据包.

  • 如果接收者(每个客户端都有它)从不在其缓存中的IP获取数据包,它将触发PeerJoined方法.

  • 缓存将在20秒后过期.如果客户端没有从缓存中的另一个客户端收到该持续时间内的数据包,它将触发PeerLeft方法.