我想知道是否有人可以帮我弄清楚为什么我在用UDP广播数据时速度慢。出于某种原因,我在计算机之间的延迟超过6秒。我正在使用线程进行接收器的发送和异步。我在Unity中使用它,数据包正在本地网络上广播。我正在尝试构建一个P2P本地网络。数据包大小约为1500字节,这只是我编写的测试脚本,但有一种方法可以改变数据包大小。
我想知道是否有更好的方式来发送或接收数据。或者是否有一个数据缓冲区,一旦我开始提高速度,我就无法读到它?是我的路由器吗?
using UnityEngine;
using System;
using System.Diagnostics;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
public class NoiseSend : MonoBehaviour
{
//Singleton
private static NoiseSend instance = null;
public static NoiseSend Instance { get { return instance; } }
//Threading
private Thread thread;
private ManualResetEvent signal = new ManualResetEvent(false);
private volatile bool isThreadRunning = false;
public System.Threading.ThreadState tState;
private Stopwatch sw;
public string fps;
//UDP Client
private IPEndPoint broadcastIP;
private UdpClient client;
public int port = 2002;
public int netID;
//Data
private string rnd;
public int sizeVariable = 500;
private string msg;
public int packetSize;
public DateTime get_UTCNow()
{
DateTime UTCNow = DateTime.UtcNow;
int year = UTCNow.Year;
int month = UTCNow.Month;
int day = UTCNow.Day;
int hour = UTCNow.Hour;
int min = UTCNow.Minute;
int sec = UTCNow.Second;
int mil = UTCNow.Millisecond;
DateTime datetime = new DateTime(year, month, day, hour, min, sec, mil);
return datetime;
}
private void Awake()
{
if (instance != null && instance != this)
{
//Destroy(this.gameObject);
}
else
{
instance = this;
}
}
// Use this for initialization
void Start()
{
setID();
SetupUDP();
StartThread();
}
private void SetupUDP()
{
client = new UdpClient();
IPAddress ip = IPAddress.Broadcast;
broadcastIP = new IPEndPoint(ip, port);
client.Connect(broadcastIP);
}
private void setID()
{
string ip = LocalIPAddress();
string[] tmp = ip.Split('.');
netID = Convert.ToInt32(tmp[tmp.Length - 1]);
}
public string LocalIPAddress()
{
IPHostEntry host;
string localIP = "";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
localIP = ip.ToString();
return localIP;
}
}
print("No Local IP Found?");
return null;
}
public void StartThread()
{
if (!isThreadRunning)
{
signal.Reset();
thread = new Thread(ContinuousThread);
thread.IsBackground = true;
thread.Name = "Noise Send";
thread.Start();
isThreadRunning = true;
}
else
{
signal.Set();
}
}
private void ContinuousThread(object param)
{
sw = new Stopwatch();
while (!signal.WaitOne(0))
{
encodeData();
byte[] encoded = ASCIIEncoding.ASCII.GetBytes(msg);
client.Send(encoded, encoded.Length);
fps = (1000f / sw.ElapsedMilliseconds).ToString();
sw.Stop();
sw.Reset();
sw.Start();
Thread.Sleep(5);
}
client.Close();
isThreadRunning = false;
}
private void encodeData()
{
for (int i = 0; i < sizeVariable; i++)
{
rnd += i.ToString();
}
int min = get_UTCNow().Minute;
int second = get_UTCNow().Second;
int milisecond = get_UTCNow().Millisecond;
msg = string.Format("{0},{1},{2},{3},{4}/", netID, rnd, min, second, milisecond);
packetSize = msg.Length;
rnd = "";
}
private void OnApplicationQuit()
{
if (client != null)
{
client.Close();
}
signal.WaitOne(0);
signal.Set();
isThreadRunning = false;
}
}
using System.Collections.Generic;
using UnityEngine;
using System.Diagnostics;
using System.Collections.Generic;
using UnityEngine;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Linq;
public class NoiseRecieve : MonoBehaviour
{
//
//Singleton
private static NoiseRecieve instance = null;
public static NoiseRecieve Instance { get { return instance; } }
//FPS.
private Stopwatch sw;
public string fps;
//UDP Client
private IPEndPoint anyIP;
private UdpClient client;
public int port = 2002;
private bool asyncListen = false;
//Data
private byte[] data;
private string decoded;
public int packetSize;
public int packets;
public List<RecievedData> input = new List<RecievedData>();
public DateTime get_UTCNow()
{
DateTime UTCNow = DateTime.UtcNow;
int year = UTCNow.Year;
int month = UTCNow.Month;
int day = UTCNow.Day;
int hour = UTCNow.Hour;
int min = UTCNow.Minute;
int sec = UTCNow.Second;
int mil = UTCNow.Millisecond;
DateTime datetime = new DateTime(year, month, day, hour, min, sec, mil);
return datetime;
}
private void Awake()
{
if (instance != null && instance != this)
{
//Destroy(this.gameObject);
}
else
{
instance = this;
}
}
// Use this for initialization
void Start()
{
sw = new Stopwatch();
SetupUDP();
startAsync();
}
private void SetupUDP()
{
client = new UdpClient(port);
IPAddress ip = IPAddress.Any;
anyIP = new IPEndPoint(ip, 0);
}
private void startAsync()
{
try
{
asyncListen = true;
client.BeginReceive(new AsyncCallback(recv), null);
}
catch (Exception e)
{
print(e);
}
}
private void recv(IAsyncResult res)
{
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, port);
byte[] received = client.EndReceive(res, ref RemoteIpEndPoint);
decoded = ASCIIEncoding.ASCII.GetString(received);
decryptData(decoded);
fps = (1000f / sw.ElapsedMilliseconds).ToString();
sw.Stop();
sw.Reset();
sw.Start();
if (asyncListen)
{
client.BeginReceive(new AsyncCallback(recv), null);
}
}
private void decryptData(string decoded)
{
bool contains = false;
List<string> msgs = decoded.Split('/').ToList();
List<string> cleaned = new List<string>();
for (int i = 0; i < msgs.Count; i++)
{
string[] tmp = msgs[i].Split(',');
if (tmp.Length == 5)
{
cleaned.Add(msgs[i]);
}
}
for (int i = 0; i < cleaned.Count; i++)
{
string[] tmp = cleaned[i].Split(',');
int netID = Convert.ToInt32(tmp[0]);
if (!created(cleaned[i]))
{
input.Add(new RecievedData(netID));
}
}
packets = cleaned.Count;
packetSize = cleaned[0].Length;
}
private bool created(string data)
{
string[] tmp = data.Split(',');
int tmpID = Convert.ToInt32(tmp[0]);
int min = Convert.ToInt32(tmp[2]);
int sec = Convert.ToInt32(tmp[3]);
int mil = Convert.ToInt32(tmp[4]);
min -= get_UTCNow().Minute;
sec -= get_UTCNow().Second;
mil -= get_UTCNow().Millisecond;
for (int i = 0; i < input.Count; i++)
{
if (input[i].id == tmpID)
{
input[i].info = string.Format("min: {0} sec: {1} mil {2}", min, sec, mil);
return true;
}
}
return false;
}
private void OnApplicationQuit()
{
if (client != null)
{
client.Close();
}
asyncListen = false;
}
[System.Serializable]
public class RecievedData
{
public int id;
public string info;
public RecievedData(int i)
{
id = i;
info = "first frame";
}
}
}