网络通讯之Socket-Tcp 分成2部分讲解:
网络通讯之Socket-Tcp(一):
1.如何理解Socket
2.Socket通信重要函数
3.Socket Tcp 调用的基本流程图
4.简单Socket实例
网络通讯之Socket-Tcp(二):
1.完善Socket实例【黏包拆包 收发数据】
2.优化Socket
3.Socket网络安全
Socket(套接字)是干什么的?应用层和传输层 的中转台或者说是桥梁。
什么是应用层,比如我们手机上的QQ应用、微信应用、和平精英、lol手游 都属于应用层。

怎么理解socket?
可以理解为是一种数据结构,数据结构主要包括:发送缓存区、接收缓存区、再加控制参数。
常用的socket 用三种类型:
1.TCP:流式socket ,面向连接、字节流传输、点对点、可靠的服务【丢失操作系统会自动重传】
2.UDP:数字报socket、无连接、不可靠【数据丢失不会重传】
3.RAW:原始socket
服务机:一个服务器程序能够接收客户端的连接请求,必有一个Socket(套接字)在等待别人的连接请求。
客户机:向服务器发送连接之前 也必须创建一个Socket(套接字)、还需要指定服务器进程的Ip地址、端口号。

Socket通信重要函数:

Scoket TCP 调用的基本流程:

简单Socket实例
实例上图


C# Socket 服务器代码:
ping一下拿到我们本机地址
1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 using System.Threading; 5 6 namespace ZhaoBuHui.GateWayServer 7 { 8 public sealed class ServerConfig 9 {10 public static string ip = "192.168.124.2";11 public static int point = 8082;12 }13 14 class Program15 {16 private static Socket m_ListenSocket;17 static void Main(string[] args)18 {19 Console.WriteLine("Hello World!");20 StartListen();21 }22 public static void StartListen()23 {24 m_ListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);25 m_ListenSocket.Bind(new IPEndPoint(IPAddress.Parse(ServerConfig.ip), ServerConfig.point));26 m_ListenSocket.Listen(100);27 Console.WriteLine("启动监听{0}成功", m_ListenSocket.LocalEndPoint.ToString());28 Thread thread = new Thread(ListenClientConnect);29 thread.Start();30 }31 /// <summary>32 /// 监听客户端链接33 /// </summary>34 /// <param name="obj"></param>35 private static void ListenClientConnect(object obj)36 {37 while (true)38 {39 try40 {41 Socket m_ClientSocket = m_ListenSocket.Accept();42 IPEndPoint iPEndPoint = (IPEndPoint)m_ClientSocket.RemoteEndPoint;43 Console.WriteLine("收到客户端IP={0},Port={1}已经连接", iPEndPoint.Address.ToString(), iPEndPoint.Port.ToString());44 45 string str = "赵不灰就是赵老三";46 byte[] data = System.Text.Encoding.UTF8.GetBytes(str);47 m_ClientSocket.BeginSend(data, 0, data.Length, SocketFlags.None, (IAsyncResult ar) =>48 {49 int len = m_ClientSocket.EndSend(ar);50 if (len > 0)51 {52 Console.WriteLine("Send Success!字节数 = " + len);53 }54 }, m_ClientSocket);55 }56 catch (Exception ex)57 {58 Console.WriteLine(ex.ToString());59 }60 }61 }62 }63 }
客户端代码:
TestSocketTcpRoutine.cs SocketTcp访问器
1 using System; 2 using System.Net; 3 using System.Net.Sockets; 4 5 public class TestSocketTcpRoutine 6 { 7 private Socket m_ClientSocket; 8 9 // 是否连接过socket 10 private bool m_bDoConnect; 11 // 是否连接成功 12 private bool m_IsConnectSuccess; 13 private Action<bool> m_ConnectCompletedHander; 14 15 /// <summary> 16 /// 接收数据缓存区 17 /// </summary> 18 private byte[] m_Receive = new byte[1024]; 19 private TestMemoryStreamUtil m_ReceiveMS = new TestMemoryStreamUtil(); 20 21 public void Connect(string ip, int point, Action<bool> bConnectComplete) 22 { 23 m_ConnectCompletedHander = bConnectComplete; 24 if ((m_ClientSocket != null && m_ClientSocket.Connected) || m_IsConnectSuccess) 25 { 26 return; 27 } 28 m_IsConnectSuccess = false; 29 try 30 { 31 m_ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 32 m_ClientSocket.BeginConnect(new IPEndPoint(IPAddress.Parse(ip), point), ConnectCallBack, m_ClientSocket); 33 } 34 catch (Exception ex) 35 { 36 m_ConnectCompletedHander?.Invoke(m_IsConnectSuccess); 37 UnityEngine.Debug.LogError(ex.ToString()); 38 } 39 } 40 41 private void ConnectCallBack(IAsyncResult ar) 42 { 43 m_bDoConnect = true; 44 if (m_ClientSocket.Connected) 45 { 46 ReceiveMsg(); 47 m_IsConnectSuccess = true; 48 } 49 else 50 { 51 m_IsConnectSuccess = false; 52 UnityEngine.Debug.LogError("服务器断开链接"); 53 } 54 m_ClientSocket.EndConnect(ar); 55 } 56 57 public void OnUpdate() 58 { 59 if (m_bDoConnect) 60 { 61 m_bDoConnect = false; 62 m_ConnectCompletedHander?.Invoke(m_IsConnectSuccess); 63 } 64 if (!m_IsConnectSuccess) return; 65 } 66 67 //接收消息 68 private void ReceiveMsg() 69 { 70 try 71 { 72 //开始接收 73 m_ClientSocket.BeginReceive(m_Receive, 0, m_Receive.Length, SocketFlags.None, (IAsyncResult ar) => 74 { 75 try 76 { 77 int len = m_ClientSocket.EndReceive(ar); 78 if (len > 0) 79 { 80 UnityEngine.Debug.Log("收到字节数 = " + len); 81 m_ReceiveMS.Position = m_ReceiveMS.Length; 82 m_ReceiveMS.Write(m_Receive, 0, len); 83 byte[] temp = new byte[len]; 84 m_ReceiveMS.Position = 0; 85 m_ReceiveMS.Read(temp, 0, len); 86 string str = System.Text.Encoding.UTF8.GetString(temp); 87 UnityEngine.Debug.Log(str); 88 } 89 else 90 { 91 UnityEngine.Debug.Log("没有收到数据 "); 92 } 93 } 94 catch (Exception ex) 95 { 96 UnityEngine.Debug.LogError(ex.ToString()); 97 } 98 }, m_ClientSocket); 99 }100 catch (Exception ex)101 {102 UnityEngine.Debug.LogError(ex.ToString());103 }104 }105 }TestMemoryStreamUtil 不知道的请点击访问m_ConnectCompletedHander 不管连接成功失败 我们都需要知道结果 进行下一步处理TestSocketManager.cs Socket管理器
1 public class TestSocketManager : System.IDisposable 2 { 3 public TestSocketTcpRoutine m_MainSocket; 4 public void Init() 5 { 6 m_MainSocket = CreateSocketTcpRoutine(); 7 } 8 public void Connect(string ip, int point, System.Action<bool> connectComplete) 9 {10 m_MainSocket.Connect(ip, point, connectComplete);11 }12 public TestSocketTcpRoutine CreateSocketTcpRoutine()13 {14 return TestGameEntry.PoolMgr.Class_Dequeue<TestSocketTcpRoutine>();15 }16 17 public void Update()18 {19 if (m_MainSocket != null)20 {21 m_MainSocket.OnUpdate();22 }23 }24 25 public void Dispose()26 {27 28 }29 }Class_Dequeue 不知道的请点击访问
TestGameEntry.cs 游戏入口
1 using UnityEngine; 2 3 public class TestGameEntry : MonoBehaviour 4 { 5 public static TestGameEntry Instance; 6 public static TestTimeManager TimeMgr { get; private set; } 7 public static TestPoolManager PoolMgr { get; private set; } 8 public static TestFsmManager FsmMgr { get; private set; } 9 public static TestProcedureManager ProcedureMgr { get; private set; }10 public static TestHttpManager HttpMgr { get; private set; }11 public static TestEventManager EventMgr { get; private set; }12 public static TestSocketManager SocketMgr { get; private set; }13 14 15 private void Awake()16 {17 Instance = this;18 }19 20 void Start()21 {22 InitManagers();23 Init();24 }25 26 void InitManagers()27 {28 TimeMgr = new TestTimeManager();29 PoolMgr = new TestPoolManager();30 FsmMgr = new TestFsmManager();31 ProcedureMgr = new TestProcedureManager();32 HttpMgr = new TestHttpManager();33 EventMgr = new TestEventManager();34 SocketMgr = new TestSocketManager();35 }36 37 void Init()38 {39 TimeMgr.Init();40 PoolMgr.Init();41 FsmMgr.Init();42 ProcedureMgr.Init();43 HttpMgr.Init();44 EventMgr.Init();45 SocketMgr.Init();46 }47 48 void Update()49 {50 TimeMgr.OnUpdate();51 PoolMgr.OnUpdate();52 ProcedureMgr.OnUpdate();53 SocketMgr.Update();54 }55 56 private void OnDestroy()57 {58 TimeMgr.Dispose();59 PoolMgr.Dispose();60 FsmMgr.Dispose();61 ProcedureMgr.Dispose();62 HttpMgr.Dispose();63 EventMgr.Dispose();64 SocketMgr.Dispose();65 }66 }TestGameEntry 不知道的请点击访问
测试代码: 按A进行连接服务器
1 if (Input.GetKeyDown(KeyCode.A))2 {3 TestGameEntry.SocketMgr.Connect("192.168.124.2", 8082, (bool isConnectSuccess) =>4 {5 UnityEngine.Debug.Log("连接192.168.124.2:8082" + (isConnectSuccess ? "成功" : "失败"));6 });7 }
注意事项:
1. BeginConnect EndConnect 成对出现
2.BeginReceive EndReceive 成对出现