网络通讯之Socket-Tcp(一)

博客 分享
0 196
张三
张三 2022-07-03 11:01:17
悬赏:0 积分 收藏

网络通讯之Socket-Tcp(一)

网络通讯之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 成对出现

posted @ 2022-07-03 10:55 赵不灰 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    张三

    张三 (王者 段位)

    821 积分 (2)粉丝 (41)源码

     

    温馨提示

    亦奇源码

    最新会员