制作加载中动画:
创建Panel,制作预制体,在Image游戏物体中添加DOTween插件,相关设置如下:
(此为DOTween Pro,需付费,也可按下面的数值编写代码解决)
Socket套接字
套接字就是将IP地址与主机端口号合并在一起后的数据,IP地址定位主机位置,端口号知道
通讯入口与出口,从而就可以实现主机的数据交换。
IP协议实现主机的网络定位
操作系统的端口实现数据的流入与流出
Socket编程基于传输层实现,所以需要指定协议类型(TCP或UDP)
TCP编程方法(C#)
字节长度关系
日常说的G,M,指的是数据容量
UTF-8编码是几个字节存储?
长度是从1个字节~6个字节存储,其中中文是3个字节
长度计量单位
B:一个字节(Byte)
KB:1024个B
MB:1024个KB
GB:1024个MB
TB:1024个GB
PB:1024个TB
手册:https://msdn.microsoft.com/zh-cn/
连接(三次握手)
同步连接
//创建套接字
Socket socket = new Socket(
AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp
);
//调用连接方法
socket.Connect("IP地址",端口号);
异步连接
//创建套接字
_TcpConnection = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
_TcpConnection.BeginConnect(Host, Port, _EndConnect, null);
//_EndConnect回调函数中执行
_TcpConnection.EndConnect(ar); //ar异步连接结果
断开(四次挥手)
同步断开
//下次使用,会创建全新的套接字
_Socket.Disconnect(false);
//关闭套接字连接,释放资源
_Socket.Close();
异步断开
socket.BeginDisconnect(false,_EndDisconnect,null);
//EndDisconnect回调函数执行
socket.EndDisconnect(异步断开连接结果);
socket.Close();
监听绑定(服务器开发)
Bind()函数实现
接收
发送
Unity测试连接相关代码:
using System;
using System.Net.Sockets;
using UnityEngine;
using UnityEngine.Events;
namespace HonorZhao
{
public class TcpDriver : MonoBehaviour
{
#region Singleton
private static readonly object _lock = new object();
private static TcpDriver _Instance;
public static TcpDriver One()
{
lock (_lock)
{
if (_Instance == null)
{
GameObject driver = new GameObject("TcpDriver");
_Instance = driver.AddComponent<TcpDriver>();
DontDestroyOnLoad(driver);
}
return _Instance;
}
}
private void Awake()
{
if (_Instance != null && _Instance != this)
{
Destroy(gameObject);
}
}
#endregion
public TCP_CONNECT_STATUS _ConnectStatus = TCP_CONNECT_STATUS.Default;
public string Host = "";
public int Port = 0;
public UnityAction ConnectedAction;
public UnityAction DisconnectedAction;
private Socket _TcpConnection;
public void BeginConnect()
{
if (_ConnectStatus != TCP_CONNECT_STATUS.Default) return;
try
{
_TcpConnection = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
_TcpConnection.BeginConnect(Host, Port, _EndConnect, null);
_ConnectStatus = TCP_CONNECT_STATUS.BeginConnect;
}
catch (Exception ex)
{
Debug.LogError($"[TCP] 连接初始化失败: {ex.Message}");
_ConnectStatus = TCP_CONNECT_STATUS.Failed;
DisconnectedAction?.Invoke();
}
}
private void _EndConnect(IAsyncResult ar)
{
try
{
_TcpConnection.EndConnect(ar);
if (_TcpConnection.Connected)
{
_ConnectStatus = TCP_CONNECT_STATUS.Connected;
ConnectedAction?.Invoke();
}
}
catch (Exception ex)
{
Debug.LogError($"[TCP] 连接失败: {ex.Message}");
_ConnectStatus = TCP_CONNECT_STATUS.Failed;
DisconnectedAction?.Invoke();
}
}
public void BeginDisconnect()
{
if (_TcpConnection == null) return;
try
{
if (_TcpConnection.Connected)
{
_TcpConnection.Shutdown(SocketShutdown.Both);
}
}
finally
{
_TcpConnection?.Close();
_TcpConnection = null;
_ConnectStatus = TCP_CONNECT_STATUS.Default;
DisconnectedAction?.Invoke();
}
}
private void OnDestroy()
{
BeginDisconnect();
}
}
}
public enum TCP_CONNECT_STATUS
{
Default,
BeginConnect,
Connected,
Failed
}
using HonorZhao;
using System.Collections;
using System.Collections.Generic;
using System.Net.Sockets;
using UnityEngine;
public class TestConnect : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
TestConnection();
}
// 测试用例
void TestConnection()
{
TcpDriver.One().Host = "echo.websocket.org";
TcpDriver.One().Port = 7;
TcpDriver.One().ConnectedAction += () => Debug.Log("Connected!");
TcpDriver.One().DisconnectedAction += () => Debug.Log("Disconnected!");
TcpDriver.One().BeginConnect();
// 5秒后断开测试
Invoke(nameof(DisconnectTest), 5f);
}
void DisconnectTest() => TcpDriver.One().BeginDisconnect();
}
该系列专栏为网课课程笔记,仅用于学习参考。