网络通讯之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 Program
15     {
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                 try
40                 {
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  赵不灰  阅读(925)  评论(0编辑  收藏  举报