背景:跟上海的公司大佬一起开发一个项目,他用 c++ 写后端 我用 c# 写前端,用 udp 通信,我这边能收发消息,可就是怎么样都用收到的消息跟另一个字符判断不了相等,麻烦了一天多的 Bug,头都大佬
用 list 遍历出来接到的字节:
byte[] data = state.UDPClient.EndReceive(ar, ref ipep);
//这里可以做一个数据检查 如:void CheckData(data)
string msgStr = Encoding.UTF8.GetString(data, 0, data.Length);
List<char> list = new List<char>();
foreach (char s in msgStr)
{
if (s != ' ')
{
list.Add(s);
}
}
msgStr = list.ToString();
foreach (var item in list)
{
print("list char" + item);
}
原理:是c++ 在发送消息的时候 会在字节后面默认加一个 \0 的字节,如果用c#接收消息,可以将最后一个字符给截掉
receiveData = client.Receive(ref remotePoint);//接收数据
receiveString = Encoding.Default.GetString(receiveData);
string s = receiveString.Substring(0, receiveString.Length - 1);
unity UDP 异步接收消息代码:
using UnityEngine;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System;
using System.Text;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
public class UDPAsyncRecvive : MonoBehaviour
{
private bool ChangeScene;
string receiveString = null;
void Start()
{
ThreadRecvive();
}
void Update()
{
if (ChangeScene)
{
ChangeScene = false;
receiveString = null;
SceneManager.LoadScene("Scene0-ZLoadingScene");
Debug.Log("切换场景");
}
}
/// <summary>
/// 开始线程接收
/// </summary>
private void ThreadRecvive()
{
//开一个新线程接收UDP发送的数据
new Thread(delegate () //delegate()也可写成 ()=>
{
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 9000);
UdpClient udp = new UdpClient(ipep);
UDPState state = new UDPState(ipep, udp);
udp.BeginReceive(CallBackRecvive, state); //异步接收
})
{ IsBackground = true }.Start(); //设置为后台线程,并开启线程
}
/// <summary>
/// 异步接收回调
/// </summary>
/// <param name="ar"></param>
private void CallBackRecvive(IAsyncResult ar)
{
UDPState state = ar.AsyncState as UDPState;
if (state != null)
{
IPEndPoint ipep = state.IPEP;
//这里接收到数据后,应该做数据完整检查,这里只是单纯做一个接收
byte[] data = state.UDPClient.EndReceive(ar, ref ipep);
//这里可以做一个数据检查 如:void CheckData(data)
string receiveString = Encoding.UTF8.GetString(data, 0, data.Length);
string msgStr = receiveString.Substring(0, receiveString.Length - 1);
if (msgStr.Trim().CompareTo("STATE-END") == 0)
{
ChangeScene = true;
Debug.Log("切换场景");
}
//继续接收下一条消息
state.UDPClient.BeginReceive(CallBackRecvive, state);
}
}
}
public class UDPState
{
private UdpClient udpClient;
public UdpClient UDPClient
{
get { return udpClient; }
}
private IPEndPoint ipep;
public IPEndPoint IPEP
{
get { return ipep; }
}
//构造函数
public UDPState(IPEndPoint ipep, UdpClient udpClient)
{
this.ipep = ipep;
this.udpClient = udpClient;
}
}