服务端:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
public enum ADDRESSFAM
{
IPv4, IPv6
}
public class SocketManager : MonoBehaviour
{
public static SocketManager _instance;
public void Awake()
{
_instance = this;
}
/// <summary>
/// 存放收到的信息的队列
/// </summary>
public Queue<string> ReceiveQueInfo = new Queue<string>();
public List<Socket> Client = new List<Socket>();
public string txt;
public Text ip;
string IP;
public Socket socket;
// Use this for initialization
void Start()
{
IP = GetIP(ADDRESSFAM.IPv4);
StartConnect();
}
// Update is called once per frame
void Update()
{
}
private void OnApplicationQuit()
{
OnClick("ClassOver");
socket.Close();
}
/// <summary>
/// 向客户端发送消息
/// </summary>
/// <param name="str">发送内容</param>
public void OnClick(string str)
{
try
{
for (int i = 0; i < Client.Count; i++)
{
AsyncSend(Client[i], str.Length + "_" + Client[i].RemoteEndPoint + "_内容:" + str);
}
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
public void StartConnect()
{
if (string.IsNullOrEmpty(IP)) return;
//创建套接字
IPEndPoint ipe = new IPEndPoint(IPAddress.Any, 8090);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//绑定端口和IP
socket.Bind(ipe);
//设置监听(最多可连接多少人)
socket.Listen(10);
//连接客户端
AsyncAccept(socket);
}
/// <summary>
/// 连接到客户端
/// </summary>
/// <param name="socket"></param>
private void AsyncAccept(Socket socket)
{
socket.BeginAccept(asyncResult =>
{
//获取客户端套接字
Socket client = socket.EndAccept(asyncResult);
Debug.Log(string.Format("请求连接_{0}", client.RemoteEndPoint));
txt = string.Format("请求连接_{0}", client.RemoteEndPoint);
ReceiveQueInfo.Enqueue(txt);
AsyncReveive(client);
Client.Add(client);
AsyncAccept(socket);
}, null);
}
/// <summary>
/// 接收消息
/// </summary>
/// <param name="client"></param>
private void AsyncReveive(Socket socket)
{
byte[] data = new byte[1024];
try
{
//开始接收消息
socket.BeginReceive(data, 0, data.Length, SocketFlags.None,
asyncResult =>
{
int length = socket.EndReceive(asyncResult);
if (length > 0)
{
Debug.Log(string.Format("接收客户端消息_{0}", Encoding.UTF8.GetString(data)));
txt = string.Format("接收客户端消息_{0}", Encoding.UTF8.GetString(data));
ReceiveQueInfo.Enqueue(txt.ToString().Trim());
AsyncReveive(socket);
}
}, null);
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="client">接受消息的客户端</param>
/// <param name="p">发送内容</param>
public void AsyncSend(Socket client, string p)
{
if (client == null || p == string.Empty) return;
//数据转码
byte[] data = new byte[1024];
data = Encoding.UTF8.GetBytes(p+"\0");
try
{
//开始发送消息
client.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult =>
{
//完成消息发送
int length = client.EndSend(asyncResult);
//输出消息
Debug.Log(string.Format("服务器发出消息:{0}", p));
}, null);
}
catch (Exception e)
{
Debug.Log(e.Message);
}
}
/// <summary>
/// 获取本机IP
/// </summary>
/// <param name="Addfam">要获取的IP类型</param>
/// <returns></returns>
public static string GetIP(ADDRESSFAM Addfam)
{
string output = "";
string ip4;
string ip6;
IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName()); //Dns.GetHostName()获取本机名Dns.GetHostAddresses()根据本机名获取ip地址组
foreach (IPAddress ip in ips)
{
if (ip.AddressFamily == AddressFamily.InterNetwork && Addfam==ADDRESSFAM.IPv4)
{
ip4 = ip.ToString(); //ipv4
output= ip4;
}
else if (ip.AddressFamily == AddressFamily.InterNetworkV6 && Addfam == ADDRESSFAM.IPv6)
{
ip6 = ip.ToString(); //ipv6
output= ip6;
}
}
return output;
}
}
客户端:
using UnityEngine;
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Net.NetworkInformation;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System.Collections;
public class SocketManager : MonoBehaviour
{
public static SocketManager _instance;
public Socket client;
public string text;
public string IP;
public IPEndPoint ipe;
void Awake()
{
_instance = this;
}
// Use this for initialization
void Start()
{
ReadIP();
AsynConnect();
}
// Update is called once per frame
void Update()
{
}
private void OnApplicationQuit()
{
AsynSend(client, "Quite");
client.Close();
}
public void ConnectToTheServer()
{
ReadIP();
//端口及IP
ipe = new IPEndPoint(IPAddress.Parse(IP), 8090);
//开始连接到服务器
client.BeginConnect(ipe, asyncResult =>
{
client.EndConnect(asyncResult);
向服务器发送消息
AsynSend(client, "Hello");
//接受消息
AsynRecive(client);
}, null);
}
/// <summary>
/// 连接到服务器
/// </summary>
public void AsynConnect()
{
Debug.Log(IP);
if (string.IsNullOrEmpty(IP))
{
return;
}
try
{
//创建套接字
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
ConnectToTheServer();
StartCoroutine(sendPing());
}
catch (Exception ex)
{
Debug.Log(ex.ToString());
}
}
/// <summary>
/// 向服务器发送消息,发送失败说明和服务器失去连接,需要重新尝试连接
/// </summary>
/// <returns></returns>
IEnumerator sendPing()
{
while (true)
{
yield return new WaitForSeconds(3);
AsynSend(client, "Ping");
}
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="socket"></param>
/// <param name="message"></param>
public void AsynSend(Socket socket, string message)
{
if (socket == null || message == string.Empty) return;
//编码
byte[] data = Encoding.UTF8.GetBytes(message);
try
{
socket.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult =>
{
//完成发送消息
int length = socket.EndSend(asyncResult);
Debug.Log(string.Format("向服务器发送消息_{0}", message));
}, null);
}
catch (Exception ex)
{
Debug.Log(ex.ToString());
ConnectToTheServer();
Debug.Log("尝试重新连接");
}
}
/// <summary>
/// 接收消息
/// </summary>
/// <param name="socket"></param>
public void AsynRecive(Socket socket)
{
byte[] data = new byte[1024];
try
{
//开始接收数据
socket.BeginReceive(data, 0, data.Length, SocketFlags.None,
asyncResult =>
{
int length = socket.EndReceive(asyncResult);
string recData = string.Format("接收服务器消息_{0}", Encoding.UTF8.GetString(data));
//Debug.Log(recData);
DataManager._instance.ReceiveInfo.Enqueue(recData);
text = recData;
AsynRecive(socket);
}, null);
}
catch (Exception ex)
{
Console.WriteLine("异常信息:", ex.Message);
}
}
/// <summary>
/// 保存IP
/// </summary>
/// <param name="iP"></param>
public void SaveIp(string iP)
{
string filepath = Application.persistentDataPath + @"/IP.xml";
if (!File.Exists(filepath))
{
XmlDocument xmlDoc = new XmlDocument();
XmlNode docNode = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
//创建root节点,也就是最上一层节点
XmlElement root = xmlDoc.CreateElement("IP");
root.InnerText = iP;
xmlDoc.AppendChild(root);
xmlDoc.Save(filepath);
Debug.Log("createIP OK!");
}
else
{
XmlDocument xmlDoc = new XmlDocument();
XmlNode docNode = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", null);
//根据路径将XML读取出来
xmlDoc.Load(filepath);
XmlNode root = xmlDoc.SelectSingleNode("IP");
root.InnerText = iP;
xmlDoc.Save(filepath);
Debug.Log(iP);
}
}
/// <summary>
/// 读取IP
/// </summary>
public void ReadIP()
{
string filepath = Application.persistentDataPath + @"/IP.xml";
if (File.Exists(filepath))
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filepath);
XmlNode root = xmlDoc.SelectSingleNode("IP");
IP = root.InnerText.ToString().Trim();
}
else
{
IP = "192.168.31.190";
SaveIp(IP);
}
}
}