UDPClient
using UnityEngine;
using System.Collections;
using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
public class UDPClient : MonoBehaviour
{
public static UDPClient instance;
//服务端的IP
string UDPClientIP;
//目标socket
Socket socket;
//服务端
EndPoint serverEnd;
//服务端端口
IPEndPoint ipEnd;
//接收的字符串
string recvStr;
//发送的字符串
string sendStr;
//接收的数据,必须为字节
byte[] recvData = new byte[1024];
//发送的数据,必须为字节
byte[] sendData = new byte[1024];
//接收的数据长度
int recvLen = 0;
//连接线程
Thread connectThread;
bool isClientActive = false;
//连接服务器时发送的vector3类型
Vector3 startVec = Vector3.zero;
bool isStartHeart = false;
public delegate void UDPClientDelegate(string str);
public event UDPClientDelegate UDPClientEvent;
[HideInInspector]
public bool isStartReceive = false;
private void Awake()
{
instance = this;
}
void Start()
{
UDPClientIP = "192.168.5.209";//服务端的IP.自己更改
UDPClientIP = UDPClientIP.Trim();
isClientActive = true;
InitSocket(); //在这里初始化
}
private void Update()
{
if (isStartHeart)
{
HeartSend();
}
//检测心跳与心跳反馈的间隔时间,
timerInterval += Time.deltaTime;
if (isStartCheckIntervalTime)
{
if (timerInterval>3f)
{
print("连接异常");
isStartCheckIntervalTime = false;
}
}
if (isStartReceive)
{
if (UDPClientEvent != null)
{
UDPClientEvent(recvStr);
}
}
}
//初始化
void InitSocket()
{
//定义连接的服务器ip和端口,可以是本机ip,局域网,互联网
ipEnd = new IPEndPoint(IPAddress.Parse(UDPClientIP),8888);
//定义套接字类型,在主线程中定义
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
//socket.Bind(ipEnd);
//定义服务端
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
serverEnd = (EndPoint)sender;
print("local:等待连接");
//建立初始连接,这句非常重要,第一次连接初始化了serverEnd后面才能收到消息
SocketSend("hello");
//SocketSendVector(startVec);
// print("local:连接");
isStartHeart = true;
//开始心跳监听
//客户端发送心跳消息后,计时器开始计时,判断3秒内是否能收到服务端的反馈
HeartSend();
//开启一个线程连接,必须的,否则主线程卡死
connectThread = new Thread(new ThreadStart(SocketReceive));
connectThread.Start();
}
//发送字符串
void SocketSend(string sendStr)
{
//清空发送缓存
sendData = new byte[1024];
//数据类型转换
sendData = Encoding.UTF8.GetBytes(sendStr);
//发送给指定服务端
socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
}
/// <summary>
/// 发送vector3
/// </summary>
/// <param name="sendVec"></param>
public void SocketSendVector(Vector3 sendVec)
{
string sendstr= sendVec.ToString();
//清空发送缓存
sendData = new byte[1024];
//数据类型转换
sendData = Encoding.UTF8.GetBytes(sendstr);
//发送给指定服务端
socket.SendTo(sendData, sendData.Length, SocketFlags.None, ipEnd);
}
//发送消息频率
float timerRate=0;
//接收服务端心跳反馈的时间间隔
float timerInterval = 0f;
byte[] heartSendData = new byte[1024];
/// <summary>
/// 心跳
/// </summary>
void HeartSend() {
// while (true) {
timerRate += Time.deltaTime;
if (timerRate >2f)
{
try
{
//清空发送缓存
heartSendData = new byte[1024];
//数据类型转换
heartSendData = Encoding.UTF8.GetBytes("alive");
//发送给指定服务端
socket.SendTo(heartSendData, heartSendData.Length, SocketFlags.None, ipEnd);
print("心跳");
isStartCheckIntervalTime = true;
}
catch (Exception e)
{
print(e.Message);
}
timerRate = 0f;
// }
}
}
//客户端接收服务器消息
void SocketReceive()
{
//进入接收循环
while (isClientActive)
{
//对data清零
recvData = new byte[1024];
try
{
//获取服务端端数据
recvLen = socket.ReceiveFrom(recvData, ref serverEnd);
if (isClientActive == false) {
break;
}
}
catch (Exception e)
{
print(e.Message);
}
//打印服务端信息
//print("local:message from--" + serverEnd.ToString());
//输出接收到的数据
if (recvLen > 0)
{
//接收到的信息
recvStr = Encoding.UTF8.GetString(recvData, 0, recvLen);
}
// print("server:" + recvStr);
//if (UDPClientEvent != null)
//{
// UDPClientEvent(recvStr);
//}
isStartReceive = true;
//心跳回馈
ServerKeepConnect(recvStr);
}
}
//发送心跳包后开始检测计时,固定时间内没有收到反馈则为连接异常
bool isStartCheckIntervalTime = false;
void ServerKeepConnect(string str) {
string receiveMsg = str;
// 当服务端收到客户端发送的alive消息时,
// timerInterval += 0.02f;
// if (timerInterval > 3f)
// {
// print("连接异常");
// }
// else
// {
if (receiveMsg == "keeping")
{
print("连接正常");
timerInterval = 0;
receiveMsg = "";
isStartCheckIntervalTime = false;
}
// }
}
//连接关闭
void SocketQuit()
{
//关闭线程
// if (connectThread != null)
//{
// connectThread.Interrupt();
// connectThread.Abort();
// }
//最后关闭socket
if (socket != null)
socket.Close();
}
void OnApplicationQuit()
{
isClientActive = false;
SocketQuit();
Thread.Sleep(25);
}
public void ButtonSend(string a)
{
SocketSend(a);
}
public void ButtonDoSomething()
{
ButtonSend("DoSomething");
}
}
网友评论