发送数据
UdpServer:
using UnityEngine;
using System.Collections;
//引入库
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.IO;
using System;
public class UdpServer : MonoBehaviour
{
//以下默认都是私有的成员
Socket socket; //目标socket
EndPoint clientEnd; //客户端
IPEndPoint ipEnd; //侦听端口
string sendStr; //发送的字符串
byte[] sendData = new byte[1024]; //发送的数据,必须为字节
Thread connectThread; //连接线程
Emulation emul;
StreamReader streamReader;
//初始化
void InitSocket()
{
//定义服务端
IPAddress IPadd = IPAddress.Parse("127.0.0.1");
ipEnd = new IPEndPoint(IPadd, 8002);
//定义套接字类型,在主线程中定义
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//服务端需要绑定ip
socket.Bind(ipEnd);
//定义客户端
IPEndPoint sender = new IPEndPoint(IPadd, 8001);
clientEnd = (EndPoint)sender;
print("waiting for UDP dgram");
}
//连接关闭
void SocketQuit()
{
//关闭线程
if (connectThread != null)
{
connectThread.Interrupt();
connectThread.Abort();
}
//最后关闭socket
if (socket != null)
socket.Close();
print("disconnect");
}
// Use this for initialization
void Start()
{
streamReader = new StreamReader(Application.dataPath + "/theDegreesdata.txt");
InitSocket(); //在这里初始化server
}
// Update is called once per frame
void Update()
{
string strLine = streamReader.ReadLine();
//print("strLine:" + strLine);
if (strLine != null)
{
string[] sts = strLine.Split(',');
if (sts.Length == 2)
{
string strX = sts[0];
string strY = sts[1];
float theX = System.Convert.ToSingle(strX);
float theY = System.Convert.ToSingle(strY);
byte[] a = BitConverter.GetBytes(theX);
byte[] b = BitConverter.GetBytes(theY);
byte[] c = new byte[a.Length + b.Length];
a.CopyTo(c, 0);
b.CopyTo(c, 4);
socket.SendTo(c, c.Length, SocketFlags.None, clientEnd);
}
}
}
void OnApplicationQuit()
{
streamReader.Close();
SocketQuit();
}
}
发送的数据为从txt文件中按行读取的经纬度信息,转为byte发送。
客户端
UDPmanager
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using UnityEngine;
public class UDPmanager : MonoBehaviour {
public float lon = 0;
public float lat = 0;
public float preLon = 0;
public float preLat = 0;
class UDPData
{
private readonly UdpClient udpClient;
public UdpClient UDPClient
{
get { return udpClient; }
}
private readonly IPEndPoint endPoint;
public IPEndPoint EndPoint
{
get { return endPoint; }
}
//构造函数
public UDPData(IPEndPoint endPoint, UdpClient udpClient)
{
this.endPoint = endPoint;
this.udpClient = udpClient;
}
}
string receiveData = string.Empty;
private Action<string> ReceiveCallBack = null;
private Thread RecviveThread;
private void Start()
{
//print("开启线程");
//开启线程
ThreadRecvive();
}
private void Update()
{
if (ReceiveCallBack != null && !string.IsNullOrEmpty(receiveData))
{
//调用处理函数对数据进行处理,RecieveCallBack参数是一个方法,所以可以对recieveData数据进行处理
//但是这个参数方法需要自己写,在NetController里面自定义
ReceiveCallBack(receiveData);
//使用之后清空接受的数据
receiveData = string.Empty;
}
}
private void OnDestroy()
{
if (RecviveThread != null)
{
RecviveThread.Abort();
}
}
//Action<string> action==RecieveCallBack参数是一个方法
public void SetReceiveCallBack(Action<string> action)
{
ReceiveCallBack = action;
}
/// <summary>
/// 开始线程接收
/// </summary>
private void ThreadRecvive()
{
print("开启线程");
//开一个新线程接收UDP发送的数据
RecviveThread = new Thread(() =>
{
//实例化一个IPEndPoint,任意IP和对应端口 端口自行修改
IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8001);//数据从哪传来的的地址和端口号
UdpClient udpReceive = new UdpClient(endPoint);
//实例化一个UdpData对象
UDPData data = new UDPData(endPoint, udpReceive);//udp数据
//开启异步接收data里面的数据
udpReceive.BeginReceive(CallBackRecvive, data);//接收数据
})
{
//设置为后台线程
IsBackground = true
};
//开启线程
RecviveThread.Start();
print("开启了!!!");
}
/// <summary>
/// 异步接收回调
/// </summary>
/// <param name="ar"></param>
private void CallBackRecvive(IAsyncResult ar)
{
print("接收数据");
try
{
//将传过来的异步结果转为我们需要解析的类型
//获取udpdata里面的UDPClient参数和IPEndPoint参数
UDPData state = ar.AsyncState as UDPData;
IPEndPoint ipEndPoint = state.EndPoint;
//结束异步接受 不结束会导致重复挂起线程卡死
byte[] data = state.UDPClient.EndReceive(ar, ref ipEndPoint);
print("data.length::" + data.Length);
byte[] byte_lon = { data[0], data[1], data[2], data[3] };
byte[] byte_lat = { data[4], data[5], data[6], data[7] };
lon = BitConverter.ToSingle(byte_lon, 0);
lat = BitConverter.ToSingle(byte_lat, 0);
//解析数据(字节流),去掉源端口目的端口和长度等,只留下数据 编码自己调整暂定为默认 依客户端传过来的编码而定
// string receiveData = Encoding.Default.GetString(data);
// Debug.Log(receiveData);
//数据的解析再Update里执行 Unity中Thread无法调用主线程的方法
//再次开启异步接收数据
state.UDPClient.BeginReceive(CallBackRecvive, state);
}
catch (Exception e)
{
Debug.LogError(e.Message);
throw;
}
}
/// <summary>
/// 发送UDP信息
/// </summary>
/// <param name="remoteIP">发送地址</param>
/// <param name="remotePort">发送端口</param>
/// <param name="message">需要发送的信息</param>
public void UDPSendMessage(string remoteIP, int remotePort, string message)
{
//将需要发送的内容转为byte数组 编码以接收端为主,自行修改
byte[] sendbytes = Encoding.Unicode.GetBytes(message);
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Parse(remoteIP), remotePort);
UdpClient udpSend = new UdpClient();
//发送数据到对应目标
udpSend.Send(sendbytes, sendbytes.Length, remoteIPEndPoint);
//关闭
udpSend.Close();
}
}
收到的数据解析回经纬度信息。