Низкая скорость передачи сокета - Win7 .Net4 - CentOSx64 Mono 2.10 - PullRequest
0 голосов
/ 16 марта 2012

Я создал простое приложение клиент / сервер, и оно отлично работает (1 МБ / с, что является максимальной скоростью, которую я настроил для отправки сервером), когда я работаю локально или в сети Lan.Но когда я пытаюсь запустить его на одном из моих выделенных серверов / VPS, моя скорость загрузки замедляется.Я использую CentOS на серверах и Mono для его запуска, Mono версия 2.10.2 и CentOs 64-битная версия.Создано с использованием framework 4.

Тест скорости:

Локальный: 1MB

Lan: 1MB

Работающий сервер в CentOS: 0 ~ 10 ~ 20 KB

Моя скорость соединения составляет 2 МБ или ~ 250 КБ.Это даст мне полную скорость несколько раз.Но очень редко, и я не понимаю, почему это иногда дает мне полную скорость, а иногда вообще не дает скорости, или почему иногда только 10 КБ, а иногда только 20 КБ.Кроме того, я запускаю клиентскую часть на моем рабочем столе Win7.Вот код для серверной и клиентской части:

Сервер:

class Program
{
    private static BackgroundWorker _ListeningWorker;
    private static BackgroundWorker _QWorker;
    private static System.Net.Sockets.Socket _Server;
    private static List<System.Net.Sockets.Socket> ConnectedClients = new List<System.Net.Sockets.Socket>();
    static void Main(string[] args)
    {
        Program._ListeningWorker = new BackgroundWorker();
        Program._ListeningWorker.WorkerSupportsCancellation = true;
        Program._ListeningWorker.DoWork += _ListeningWorker_DoWork;
        Program._QWorker = new BackgroundWorker();
        Program._QWorker.WorkerSupportsCancellation = true;
        Program._QWorker.DoWork += _QWorker_DoWork;
        Program.Start();
        while (true)
        {
            Console.Clear();
            Console.WriteLine("1.0.0.1");
            Console.WriteLine(Program.ConnectedClients.Count.ToString());
            System.Threading.Thread.Sleep(1000);
        }
    }
    public static bool Start()
    {
        if (!Program._ListeningWorker.IsBusy)
        {
            Program._Server = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, 8081);
            Program._Server.Bind(ipLocal);
            Program._Server.Listen(10);

            Program._ListeningWorker.RunWorkerAsync();
            Program._QWorker.RunWorkerAsync();
        }

        return true;
    }
    private static void _ListeningWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        while (!Program._ListeningWorker.CancellationPending)
        {
            if (Program._Server.Poll(10, SelectMode.SelectRead))
            {
                lock (ConnectedClients)
                {
                    Program.ConnectedClients.Add(Program._Server.Accept());
                }
            }
            System.Threading.Thread.Sleep(1);
        }
        Program._Server.Close();
    }
    private static void _QWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        byte[] array = new byte[1024];
        Random random = new Random();
        while (!Program._QWorker.CancellationPending)
        {
            if (ConnectedClients.Count > 0)
            {
                System.Net.Sockets.Socket[] st;
                lock (ConnectedClients)
                {
                    st = new System.Net.Sockets.Socket[Program.ConnectedClients.Count];
                    ConnectedClients.CopyTo(st);
                }

                foreach (System.Net.Sockets.Socket ser in st)
                {

                    random.NextBytes(array);
                    try
                    {
                        ser.BeginSend(array, 0, array.Length, SocketFlags.None, (AsyncCallback)delegate(IAsyncResult ar)
                        {
                            try
                            {
                                ser.EndSend(ar);
                            }
                            catch (Exception)
                            {
                                iDissconnected(ser);
                            }
                        }, null);
                    }
                    catch (Exception)
                    {
                        iDissconnected(ser);
                    }
                }
            }
            System.Threading.Thread.Sleep(1);
        }
        Program._Server.Close();
    }
    internal static void iDissconnected(System.Net.Sockets.Socket client)
    {
        lock (ConnectedClients)
            for (int i = 0; i < ConnectedClients.Count; i++)
                if (ConnectedClients[i].Equals(client))
                {
                    ConnectedClients.RemoveAt(i);
                    i--;
                }
    }
}

Клиент:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Enter IP Address: ");
        string Address = Console.ReadLine();
        Console.WriteLine();
        ushort Port = 8081;
        System.Net.Sockets.Socket Client;
        Client = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        Client.Connect(Address, (int)Port);
        Console.WriteLine("Connected");
        int p = 0;
        int t = Environment.TickCount;
        while (true)
        {
            if (Client.Available > 0)
            {
                byte[] z = new byte[1024];
                int r = Client.Receive(z); ;
                p += r;
            }
            else
            {
                System.Threading.Thread.Sleep(10);
            }
            if (Environment.TickCount - t >= 1000)
            {
                t = Environment.TickCount;
                Console.WriteLine(Program.FormatFileSizeAsString(p) + " Readed,");
                p = 0;
            }
        }
    }
    public static string FormatFileSizeAsString(int len)
    {
        if (len < 750 && len > 0)
            return "0.0 B ~";
        string[] Suffix = { "B", "KB", "MB", "GB", "TB" };
        int i;
        double dblSByte = len;
        for (i = 0; (int)(len / 1024) > 0; i++, len /= 1024)
            dblSByte = len / 1024.0;
        return String.Format("{0:0.0} {1}", dblSByte, Suffix[i]);
    }
}

Спасибо всем, Пожалуйста, скажите мне, что вы думаете о возможных проблемах.

1 Ответ

0 голосов
/ 29 января 2013

Это было своего рода ограничение ISP для каждого соединения. Решение было забавным. Раньше я отправлял заголовок HTTP перед моим запросом, и из-за этого провайдер увеличивал скорость.

...