局域网内实现 服务器自动广播Ip 客户端自动获取连接

局域网内实现 服务器自动广播Ip 客户端自动获取连接

1需求 分析

1 教师端需要使用UDP 协议广播给局域网所有客户端,每隔固定时间广播一次

2 学生端需要监听固定端口Ip,收到后保留下来,同时保存标识,在IP没有发生变化时,不需弹出Ip弹窗

2制作

教师端服务器 代码

使用控制台做服务器,自己拷贝到服务器简单修改下

using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
using UnityEngine.Networking;

public class Server : MonoSingleton<Server>
{
	private static Socket sock;
	public static IPEndPoint iep1;
	private static byte[] data;
	private Thread t;
	public int udpPort = 9050;
	public string ip = "";

	public void Start()
	{
		GetIpLocal();
		BroadcastIP(); 
	}

	public void BroadcastIP()
	{
		sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

		iep1 = new IPEndPoint(IPAddress.Broadcast, udpPort);

		data = Encoding.ASCII.GetBytes("111");

		sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);

		t = new Thread(BroadcastMessage);
		t.Start();
	}

	private void BroadcastMessage()
	{
		while (true)
		{
			sock.SendTo(data, iep1);
			Thread.Sleep(2000);  ///每2000 毫秒广播一次数据
			Debug.Log("每2000 毫秒广播一次数据");
		}
	}

	/// <summary>
	///  c#  本机Ip
	/// </summary>
	/// <returns></returns>
	private string GetIP()
	{
		NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
		foreach (NetworkInterface adater in adapters)
		{
			if (adater.Supports(NetworkInterfaceComponent.IPv4))
			{
				UnicastIPAddressInformationCollection UniCast = adater.GetIPProperties().UnicastAddresses;
				if (UniCast.Count > 0)
				{
					foreach (UnicastIPAddressInformation uni in UniCast)
					{
						if (uni.Address.AddressFamily == AddressFamily.InterNetwork)
						{
							//m_ip = uni.Address.ToString();
							return uni.Address.ToString();
						}
					}
				}
			}
		}
		return null;
	}
	/// <summary>
	/// unity  本地Ip
	/// </summary>
	/// <returns></returns>
	public string GetIpLocal()
	{
#if UNITY_5
		ip = Network.player.ipAddress;
		return ip;
#else
		ip = GetIP(ADDRESSFAM.IPv4);
		return ip ;
#endif

	}


	public static string GetIP(ADDRESSFAM Addfam)
	{
		//Return null if ADDRESSFAM is Ipv6 but Os does not support it
		if (Addfam == ADDRESSFAM.IPv6 && !Socket.OSSupportsIPv6)
		{
			return null;
		}

		string output = "";

		foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
		{
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
			NetworkInterfaceType _type1 = NetworkInterfaceType.Wireless80211;
			NetworkInterfaceType _type2 = NetworkInterfaceType.Ethernet;

			if ((item.NetworkInterfaceType == _type1 || item.NetworkInterfaceType == _type2) && item.OperationalStatus == OperationalStatus.Up)
#endif
			{
				foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
				{
					//IPv4
					if (Addfam == ADDRESSFAM.IPv4)
					{
						if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
						{
							output = ip.Address.ToString();
							Debug.Log("啊" + output);
						}
					}

					//IPv6
					else if (Addfam == ADDRESSFAM.IPv6)
					{
						if (ip.Address.AddressFamily == AddressFamily.InterNetworkV6)
						{
							output = ip.Address.ToString();
						}
					}
				}
			}
		}
		return output;
	}
}

public enum ADDRESSFAM
{
	IPv4, IPv6
}

学生端代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System;
using UnityEngine.UI;

public class ClitetGetServerIp : MonoBehaviour
{
	public static ClitetGetServerIp Instance;
	byte[] data;
	string Error_Message;

	private Thread t;
	public int udpPort = 9050;
	public string ip;

	public string Ip
	{
		get
		{
			return ip;
		}
		private set { }
	}
	public bool isGetServerIp;

	public GameObject canvas;
	public Button button;
	public Text iptxt;

	public bool isCheck;
	void Awake()
	{
		Instance = this;
		GetSeverIP();
		//PlayerPrefs.DeleteAll();
		button.onClick.AddListener(() => {
			
			PlayerPrefs.SetString("Ip", ip);
			GameInit.Init();
			canvas.SetActive(false);
		});
	}

	private void Update()
	{
		if (isGetServerIp)
		{
			if (!isCheck)
			{
				if (PlayerPrefs.HasKey("Ip"))
				{
					Debug.Log("Ip");
					string oldIp = PlayerPrefs.GetString("Ip");
					if (string.Equals(ip, oldIp))
					{
						canvas.gameObject.SetActive(false);
						GameInit.Init();
					}
					else
					{
						canvas.gameObject.SetActive(true);
					}
				}
				else
				{
					Debug.Log("显示");
					canvas.gameObject.SetActive(true);

				}
				iptxt.text = ip;
				isCheck = true;
			}

		}
	}

	void GetSeverIP()
	{
		if (isGetServerIp) return;

		try
		{
			t = new Thread(Receive);
			t.Start();
		}
		catch (Exception e)
		{
			Debug.LogError("错误信息:" + e.Message);
		}
	}

	Socket sock;
	void Receive()
	{
		sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
		IPEndPoint iep = new IPEndPoint(IPAddress.Any, udpPort);
		sock.Bind(iep);
		EndPoint ep = (EndPoint)iep;

		byte[] data = new byte[1024];
		int recv = sock.ReceiveFrom(data, ref ep);
		string stringData = Encoding.ASCII.GetString(data, 0, recv);

		Debug.Log(String.Format("received: {0} from: {1}", stringData, ep.ToString()));
		string[] condition = { ":" };
		ip = ep.ToString().Split(condition, StringSplitOptions.None)[0];
		isGetServerIp = true;
		sock.Close();

	}



}

3 百度网盘工程文件:

链接:https://pan.baidu.com/s/149ErALcszXynS9BoCNi0VQ
提取码:osyk
复制这段内容后打开百度网盘手机App,操作更方便哦

版本: unity 5.6.6

4  服务器其他socket 连接时,调用获取本地IP时注意

Server.GetIP(ADDRESSFAM.IPv4))   在断网时不会返回数值,需要设置为127.0.0.1 。否则断网时无法在一台电脑同时跑服务器和客户端

如下代码示例 中 :string.IsNullOrEmpty(Server.GetIP(ADDRESSFAM.IPv4))  进行判断

  public static int  m_Point = 10110;
		public static Socket m_ServerSocket;

	    public void Init()
	   {
		  
		 Main();
		 InitDBModle();
	   }

	   static void Main()
		{
		    // Debug.Log(Server.Instance.GetIpLocal());
		    // Debug.Log(Server.GetIP(ADDRESSFAM.IPv4)); 
		    
			m_ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
		    if (string.IsNullOrEmpty(Server.GetIP(ADDRESSFAM.IPv4)))
		    { 
			   m_ServerSocket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), m_Point));
		    }
		    else
		    {
			  m_ServerSocket.Bind(new IPEndPoint(IPAddress.Parse(Server.GetIP(ADDRESSFAM.IPv4)), m_Point));

		    }
		
			m_ServerSocket.Listen(3000);
		    Debug.Log("启动监听成功");
			Thread mthread = new Thread(ListenClientCallBack);
			mthread.Start();
			
		}
		public static void ListenClientCallBack()
		{
		   // Debug.Log("00000000000000000000");
			while (true)
			{
				Socket socket = m_ServerSocket.Accept();
				
			    Debug.LogFormat("客户端{0}已经连接", socket.RemoteEndPoint.ToString());
				Role role = new Role();
			    role.LoginTime = System.DateTime.Now;
			    Debug.Log(role.LoginTime);
			    ClientSocket clientSocket = new ClientSocket(socket, role);
				//role.clientSocket = clientSocket;
				RoleMgr.Instance.GetRoles.Add(role);
		}

		}