当前位置:网站首页>Unity C# 网络学习(四)
Unity C# 网络学习(四)
2022-04-23 04:54:00 【zzzsss123333】
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);
}
}
版权声明
本文为[zzzsss123333]所创,转载请带上原文链接,感谢
https://blog.csdn.net/zzzsss123333/article/details/124338949
边栏推荐
- 信息学奥赛一本通 1955:【11NOIP普及组】瑞士轮 | OpenJudge 4.1 4363:瑞士轮 | 洛谷 P1309 [NOIP2011 普及组] 瑞士轮
- Druid -- JDBC tool class case
- MySQL - index
- redis和mysql区别
- 【数据库】MySQL单表查询
- Unity攝像頭跟隨鼠標旋轉
- Pixel 5 5g unlocking tutorial (including unlocking BL, installing edxposed and root)
- Pixel mobile phone brick rescue tutorial
- The object needs to add additional attributes. There is no need to add attributes in the entity. The required information is returned
- Innovation training (V) configuration information
猜你喜欢
Spark optimization
Arduino UNO r3+LCD1602+DHT11
View, modify and delete [database] table
使用model.load_state_dict()时,出现AttributeError: ‘str‘ object has no attribute ‘copy‘
CLion+OpenCV identify ID number - detect ID number
Sword finger offer: the median in the data stream (priority queue large top heap small top heap leetcode 295)
COM in wine (2) -- basic code analysis
【数据库】MySQL多表查询(一)
What is a data island? Why is there still a data island in 2022?
Luogu p1858 [multi person knapsack] (knapsack seeking the top k optimal solution)
随机推荐
What is a data island? Why is there still a data island in 2022?
Manually write smart pointer shared_ PTR function
[database] MySQL multi table query (I)
泰克示波器DPO3054自校准SPC失败维修
Learning Android II from scratch - activity
【数据库】表的查看、修改和删除
[WinUI3]编写一个仿Explorer文件管理器
C list field sorting contains numbers and characters
Repair of self calibration SPC failure of Tektronix oscilloscope dpo3054
How can continuous integration (CI) / continuous delivery (CD) revolutionize automated testing
Informatics Olympiad 1955: [11noip popularization group] Swiss round | openjudge 4.1 4363: Swiss round | Luogu p1309 [noip2011 popularization group] Swiss round
Recommended scheme of national manufactured electronic components
Eight misunderstandings that should be avoided in data visualization
Wine (COM) - basic concept
Com alibaba. Common methods of fastjson
[2022 ICLR] Pyraformer: Low-Complexity Pyramidal Attention for Long-Range 时空序列建模和预测
Innovation training (XI) airline ticket crawling company information
Wechat payment function
Innovation training (IV) preliminary preparation - server
Customize the navigation bar at the top of wechat applet (adaptive wechat capsule button, flex layout)