Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

同步方法UDP客户端实现示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
public class UdpNetMgr : MonoBehaviour
{
private static UdpNetMgr instance;
public static UdpNetMgr Instance => instance;

private EndPoint serverIpPoint;

private Socket socket;

private bool isClosed;
//两个容器
//接收和发送消息的队列 主要用于多线程
private Queue<BaseMsg> sendQueue = new Queue<BaseMsg>();
private Queue<BaseMsg> ReceiveQueue = new Queue<BaseMsg>();

private byte[] cacheBytes = new byte[512];
private void Awake()
{
instance = this;
DontDestroyOnLoad(this);
}
private void Update()
{
if (ReceiveQueue.Count > 0)
{
BaseMsg msg = ReceiveQueue.Dequeue();
switch (msg)
{
case PlayerMsg playerMsg:
print(playerMsg.playerID);
print(playerMsg.playerData.name);
print(playerMsg.playerData.atk);
print(playerMsg.playerData.lev);
break;
}
}
}

/// <summary>
/// 启动客户端socket相关的方法
/// </summary>
/// <param name="ip">远端服务器的IP</param>
/// <param name="port">远端服务器的端口</param>
public void StartClient(string ip, int port)
{
//不重复开启
if (isClosed)
return;

//先记录服务器地址,一会发消息使用
serverIpPoint = new IPEndPoint(IPAddress.Parse(ip),port);
IPEndPoint clientIpPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8081);
try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Bind(clientIpPoint);
isClosed = false;
ThreadPool.QueueUserWorkItem(ReceiveMsg);
ThreadPool.QueueUserWorkItem(SendMsg);
}
catch (Exception e)
{
Console.WriteLine("启动Socket出问题"+e.Message);
throw;
}
}
//多线程发送消息
private void SendMsg(object obj)
{
while (socket!=null&&!isClosed)
{
if (sendQueue.Count > 0)
{
try
{
socket.SendTo(sendQueue.Dequeue().Writing(),serverIpPoint);
}
catch (SocketException e)
{
print("发送消息出错"+e.ErrorCode+e.Message);
}
}
}
}
/// <summary>
/// 发送消息
/// </summary>
/// <param name="msg">消息内容</param>
public void Send(BaseMsg msg)
{
sendQueue.Enqueue(msg);
}
//多线程接收消息
private void ReceiveMsg(object obj)
{
EndPoint tmpIpPoint = new IPEndPoint(IPAddress.Any, 0);
int nowIndex;
int msgID;
int msgLength;
while (socket!=null&&!isClosed)
{
if (socket.Available>0)
{
try
{
socket.ReceiveFrom(cacheBytes, ref tmpIpPoint);
//为了避免非服务器发来的 骚扰消息
//如果发现不是服务器 就不处理
if (!tmpIpPoint.Equals(serverIpPoint))
continue;
//处理服务器发来的消息
nowIndex = 0;
//解析ID
msgID = BitConverter.ToInt32(cacheBytes, nowIndex);
nowIndex += 4;
//解析长度
msgLength = BitConverter.ToInt32(cacheBytes, nowIndex);
nowIndex += 4;
//解析消息体
BaseMsg msg = null;
switch (msgID)
{
case 1001:
msg = new PlayerMsg();
//反序列化消息体
msg.Reading(cacheBytes, nowIndex);
break;
}
if (msg != null)
ReceiveQueue.Enqueue(msg);
}
catch (SocketException e)
{
print("接收消息出问题" + e.ErrorCode + e.Message);
}
catch (Exception e)
{
print("接收消息出问题(非网络)" + e.Message);
}
}
}
}

/// <summary>
/// 关闭socket
/// </summary>
public void Close()
{
if (socket != null)
{
isClosed = true;
socket.Shutdown(SocketShutdown.Both);
socket.Close();
socket = null;
}
}

private void OnDestroy()
{
Close();
}
}

评论