概述
Unity C# 网络学习(四)
一.心跳消息
- 我们需要监测客户端因为网络或用户断开连接
- 可以使用socket.Poll(1000, SelectMode.SelectRead)为真时断开连接,但是这个方法不稳定
- 我们可以每过一会向服务器发送消息(心跳消息)来进行判断客户端是否和服务器相互连接
心跳包的定义
public class HeartMsg : MsgBase
{
public override int GetLength()
{
return 8;
}
public override byte[] GetBytes()
{
var buffer = new byte[GetLength()];
var index = 0;
WriteInt(buffer,ProtoID,ref index);
WriteInt(buffer, GetLength() - 8, ref index);
return buffer;
}
public override void Reading(byte[] buffer, int startIndex = 0)
{
base.Reading(buffer, startIndex);
}
public override int ProtoID => 1002;
}
服务端的处理
记录上一次收到心跳包的时间
private long _fontTime = -1;
else if (state is HeartMsg)
{
Console.WriteLine("收到来自:{0}的心跳消息!!!",socket.RemoteEndPoint);
_fontTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
}
对时间进行检测,判断是否超时
private void CheakTimeOut()
{
if(_fontTime!=-1&& DateTime.Now.Ticks / TimeSpan.TicksPerSecond - _fontTime >= 5f)
{
Program.serverSocket.AddNeedRemoveClientSocket(this);
}
}
服务端移除断开连接的客户端
将需要移除的客户端连接放入要移除的列表中,在特定位置进行移除
二.Socket异步API(一)
public class Lesson11 : MonoBehaviour
{
private byte[] buffer = new byte[1024 * 1024];
private void Start()
{
CountDownAsync(5, () =>
{
Debug.Log("执行完成!");
});
CountDownAsync(5);
Debug.Log("ok");
//Socket异步API
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IPv4);
//服务器相关
socket.BeginAccept(AcceptHandle, socket);
//客户端相关
socket.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8080), ConnectHandle, socket);
//双端通用
socket.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,ReceiveHandle,socket);
//发送消息
socket.BeginSend(new byte[10], 0, 10, SocketFlags.None,SendHandle, socket);
}
private void SendHandle(IAsyncResult ar)
{
try
{
var s = ar.AsyncState as Socket;
var num = s.EndSend(ar);
}
catch (Exception e)
{
Debug.Log(e);
}
}
private void ReceiveHandle(IAsyncResult ar)
{
try
{
var s = ar.AsyncState as Socket;
var num = s.EndReceive(ar);
s.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, ReceiveHandle, s);
}
catch (Exception e)
{
Debug.Log(e);
}
}
private void ConnectHandle(IAsyncResult ar)
{
try
{
var s = ar.AsyncState as Socket;
s.EndConnect(ar);
}
catch (Exception e)
{
Debug.Log(e);
}
}
private void AcceptHandle(IAsyncResult result)
{
try
{
var s = result.AsyncState as Socket;
var acceptSocket = s.EndAccept(result);
s.BeginAccept(AcceptHandle, s);
}
catch (Exception e)
{
Debug.Log(e);
}
}
private void CountDownAsync(int second,UnityAction action)
{
var t = new Thread(() =>
{
while (true)
{
Debug.Log(second);
Thread.Sleep(1000);
second--;
if(second==0)
break;
}
action?.Invoke();
});
t.Start();
Debug.Log("开始倒计时");
}
private async void CountDownAsync(int second)
{
await Task.Run(() =>
{
while (true)
{
Debug.Log(second);
Thread.Sleep(1000);
second--;
if(second==0)
break;
}
});
Debug.Log("倒计时结束");
}
}
三.Socket异步API(二)
public class Lesson12 : MonoBehaviour
{
private void Start()
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//服务端
var e1 = new SocketAsyncEventArgs();
e1.Completed += (s, args) =>
{
if (args.SocketError == SocketError.Success)
{
var acceptSocket = args.AcceptSocket;
(s as Socket)?.AcceptAsync(args);
}
else
{
Debug.Log(args.SocketError);
}
};
socket.AcceptAsync(e1);
//客户端
var e2 = new SocketAsyncEventArgs();
e2.Completed += (s, args) =>
{
if (args.SocketError == SocketError.Success)
{
Debug.Log("连接成功!");
}
else
{
Debug.Log(args.SocketError);
}
};
socket.ConnectAsync(e2);
//发送消息
var e3 = new SocketAsyncEventArgs();
e3.SetBuffer(new byte[1024], 0, 1024);
e3.Completed += (s, args) =>
{
if (args.SocketError == SocketError.Success)
{
Debug.Log("发送成功!");
}
else
{
Debug.Log(args.SocketError);
}
};
socket.SendAsync(e3);
//接收消息
var e4 = new SocketAsyncEventArgs();
e4.SetBuffer(new byte[1024 * 1024], 0, 1024 * 1024);
e4.Completed += (s, args) =>
{
if (args.SocketError == SocketError.Success)
{
//args.BytesTransferred接收的字节数
var s1 = Encoding.UTF8.GetString(args.Buffer,0,args.BytesTransferred);
//接收一次后继续接收
e4.SetBuffer(0,args.Buffer.Length);
(s as Socket)?.ReceiveAsync(args);
}
else
{
Debug.Log(args.SocketError);
}
};
socket.ReceiveAsync(e4);
}
}
最后
以上就是长情蜜蜂为你收集整理的Unity C# 网络学习(四)Unity C# 网络学习(四)的全部内容,希望文章能够帮你解决Unity C# 网络学习(四)Unity C# 网络学习(四)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复