套接字+Socket连接
制作加载中动画:
创建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 Singletonprivate 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);}}#endregionpublic 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 updatevoid 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();}
该系列专栏为网课课程笔记,仅用于学习参考。