C#UDP发送和接收缓慢

时间:2017-03-22 23:45:35

标签: c# sockets networking unity3d udp

我想知道是否有人可以帮我弄清楚为什么我在用UDP广播数据时速度慢。出于某种原因,我在计算机之间的延迟超过6秒。我正在使用线程进行接收器的发送和异步。我在Unity中使用它,数据包正在本地网络上广播。我正在尝试构建一个P2P本地网络。数据包大小约为1500字节,这只是我编写的测试脚本,但有一种方法可以改变数据包大小。

  • 我已尝试过不同的端口
  • 我尝试过15字节的数据包
  • 我发送并接收同一个插座?
  • 转到同一台计算机只需不到1毫秒

我想知道是否有更好的方式来发送或接收数据。或者是否有一个数据缓冲区,一旦我开始提高速度,我就无法读到它?是我的路由器吗?

发件人代码

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";
        }
    }
}

0 个答案:

没有答案