powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Прокачать большой поток через UDP
27 сообщений из 27, показаны все 2 страниц
Прокачать большой поток через UDP
    #39348793
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем доброго времени суток.

Стоит задача, прокачать через UDP большой поток "некоторых" данных, и записать его на диск. Для того чтобы определить возможности конкретного железа для решения задачи (получения потока данных и записи его на диск).
Конкретное железо - это промышленный одноплатный комп, предположительно на атоме.

Собственно это было реализовано на C#, с двумя буферами, очередью записи на твердотельный диск, и это все отлично работает на машинах уровня i5 2009 года. Через 4 UDP сокета прокачивается до 500мбит/сек без потерь данных.

Когда стали пробовать запускать на атоме (неттоп), выяснилось, что UDP поток начинает начинает резаться.
если скорость выше 22мбит/сек на один сокет - появляются потерии
и если запускать несколько сокетов - то предел суммарной скорости примерно 85мбит/сек. а нужно 300.

Дополнительной обработки в ПО нет, просто принимается пакет, потом в буфер, потом буфер в очередь, потом очередь на диск.
Профайлер показывает 93% - это функция Receive. И если выключаю дальнейшую обработку, а только чтение из сокета - те же самые проблемы.

То есть тормоза не в "обработке и буферизации" а в том что пакеты на доходят до системной функции Receive. Либо скорость получения из неё буфера - не достаточна.

Для эксперимента, пробовал на тот же АТОМ копировать файл через сеть на диск - скорость до 500мбит/сек.
То есть как-то же это прокачивается!? Понятно что без буферизации, и скорей всего сразу пишется на диск, но сокеты то принимают такой большой поток.

Сперва пробовал делать на асинхронных сокетах
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
        public virtual void ReceiveCallback(IAsyncResult ar)
        {
                var callbackInPoint = ((UdpState)(ar.AsyncState)).inPoint;

                var udpBuffer = udpClient.EndReceive(ar, ref callbackInPoint);

                RecievedBytesTotal += (ulong)udpBuffer.Length;

                //bufferManager.Add(ref udpBuffer);

                if (DoWork)
                    udpClient.BeginReceive(ReceiveCallback, state);
        }



потом всякие вариации на синхронном
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
                    ...
                    while (udpClient.Available > 0 && DoWork)
                    {
                        var buff = new byte[len];
                        var rcv = udpClient.Client.Receive(buff);//, len, SocketFlags.None);

                        RecievedBytesTotal += (ulong)rcv;
                        RecievedPacktesTotal++;

                        //bufferManager.Add(ref buff, ref rcv);

                    }//while


конкретно тот вариант что выше - оказался чуток тормознутей чем асинхронный.

Входной буфер сокета пробовал увеличивать до неприличных 100мб - горох об стену.

Асинхронный сокет вызывается с каждой датаграммой, что очевидно может притормаживать при большом потоке .
Когда я начинал делать варианты с синхронным сокетом, у меня была надежда что можно выгребсти сразу весь системный буфер UDP, но блин каждая Receive возвращает по прежнему по одной датаграмме.

Собственно вопросы:
1) Реально ли технически на атоме прокачать через 1..8 UDP сокетов 300мбит/сек без потерь? Или это под силу только TCP? Или нужно поднимать уровень железа до i3 индексом U?
2) Есть ли возможность получать за "шаг" не по одной датаграмме (~1000байт) а выгребать весь входящий UDP буфер.
3) Какие есть хитрые способы работы с сокетами для прокачки больших данных?
4) Мантры линукс и голый "С", в смысле если подобное реализовать на них, UDP сокеты будут работать быстрее и пакеты теряться не будут?
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39348799
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчик1) Реально ли технически на атоме прокачать через 1..8 UDP сокетов 300мбит/сек без потерь ?ВикипедияТаким образом, UDP предоставляет ненадёжный сервис, и датаграммы могут прийти не по порядку, дублироваться или вовсе исчезнуть без следа. UDP подразумевает, что проверка ошибок и исправление либо не нужны, либо должны исполняться в приложении.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39348811
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей ККифирчик1) Реально ли технически на атоме прокачать через 1..8 UDP сокетов 300мбит/сек без потерь ?ВикипедияТаким образом, UDP предоставляет ненадёжный сервис, и датаграммы могут прийти не по порядку, дублироваться или вовсе исчезнуть без следа. UDP подразумевает, что проверка ошибок и исправление либо не нужны, либо должны исполняться в приложении.
Подловили )
Перефразирую, с потерями не больше 5%.
Пока что для 4х сокетов картина маслом такая
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
------------------------------------
|mbit/sec  | mbit/sec     |  lost  |
|    all   | for socket   |   %    |
------------------------------------
|   43,95  |	10,99     |  0,00% |
|   87,89  |	21,97     |  0,00% |
|  109,86  |	27,47     |  5,39% |
|  131,84  |	32,96     |  7,51% |
|  175,78  |	43,95     | 26,42% |
|  219,73  |	54,93     | 45,66% |
|  263,67  |	65,92     | 62,36% |
------------------------------------
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39348823
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На С баловался с UDP. Можешь почитать

Одного сокета достаточно, по сути 8 сокетов это в 8 раз больше буфер. Надо просто увеличить буфер.
Пакеты могут теряться при помещении в буфер отправки, если он переполнен, то они просто игнорируются. Т.е. теряет отправитель. Отправку лучше делать в блокирующем режиме 17346638 , тогда если буфер отправки полный будет ожидание, а не потеря пакета.
Тоже самое при приеме. Увеличивай буферы обоих сокетов (отправляющего и принимающего).

Второй момент - размер пакета. Он должен быть максимально большим (MTU - 28). Почитай что такое MTU. Если у тебя локалка, то ставь 1472 байта. В гигабите есть Jumbo frame , вроде как 16000 байт максимум, но я с этим не разбирался. Превысишь MTU, начнется дефрагментация пакетов, а это либо тормоза, либо потери.

Третий - потери это нормально. Закладывай в свой протокол контроль доставки и повторный запрос потерянного. В локалке потерь мало, а если через инет будешь слать, то там надо скорость регулировать, иначе переполнишь буфер приема какого-нибудь шлюза по дороге и он потеряет хвост твоего "залпа".

Четвертый - пакеты могут приходить не в том порядке как отправлены. Вполне возможно получить например в таком порядке 1,2,5,3,4.

TCP чем не устроил?
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39348836
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TTCP чем не устроил?+1
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39348850
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
Почитал, вижу был очень бурный секс )))
В моем случае, проблема больше не в отправке. В компе который "генерирует" поток я не ограничен, и могу легко 900 мегабит выжать. С MTU - уже тоже ткнулся носом, пакеты до 1400 байт. И рабочий десктоп - принимает пакеты... 900мбит я не считал потери, а на 400 - точно пакет в пакет. С мощными компами - проблем нет.

Мне сейчас не нужно делать протокол, или гарантировать порядок. Мне нужно сказать какой по производительности комп нужен чтоб от некоторого оборудования получить поток 300мбит/сек и записать его на диск.
UDP я выбрал как более простой вариант, и что это должно быть быстрее по скорости.
TCP - будет быстрее передавать?

Промышленные компы бывают разные. Можно что-нить типа ordroid взять, а можно Intel Atom, которых там не хилая линейка, разных поколений и с разным количеством ядер/потоков, а можно селерон, а можно i3xxxxU или i5xxxxU или i7xxxxU. И чем мощнее - тем больше потребление и цена. Мне нужно понять где оптимальное решение в моей задаче.

То есть задача тестового ПО - определить необходимые характеристики железа.

пока что я вижу, что при реализации на .NET - на i5xxxU это шуршит без проблем.
на Atom 330 - больше 22 мбит/сек на сокет или более 84мбит/суммарно начинаются потерии... в геометрической прогрессии, табличка в предыдущем посте - для атома.

Вопрос - я уперся в производительность железа и надо брать железо мощнее, или я на столько криворукий программист, и есть более быстрые способы ловить пакеты, в частности я предположил что как-то можно не по одному пакету читать а выгребать весь буфер сразу. или (что мне кажется маловероятным) прослойка .NET над системным сокетом вносит такие тормоза и ограничения, и использование "C" в разы все ускорило бы.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39348874
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикUDP я выбрал как более простой вариант, и что это должно быть быстрее по скорости.
TCP - будет быстрее передавать?
Затести. Возможно быстрее, возможно чуть медленнее.
Для простого замера скорости UDP я бы советовал считать объем принятого в секунду и не заморачиваться на потери.
Тот топик для баловства поднимал. Просто любопытно было сколько выжму из гигабита. По TCP у меня копирование файла с SSD на SSD идет 103 Мб/сек, т.е. гигабит по TCP, по UDP результаты были скромнее.

В инете UDP быстрее, в локалке - сомневаюсь.

По сути TCP это и есть UDP плюс решение всех проблем которые я описал. Т.е. в итоге ты напишешь самодельный TCP.

КифирчикВопрос - я уперся в производительность железа и надо брать железо мощнее, или я на столько криворукий программист, и есть более быстрые способы ловить пакеты, в частности я предположил что как-то можно не по одному пакету читать а выгребать весь буфер сразу. или (что мне кажется маловероятным) прослойка .NET над системным сокетом вносит такие тормоза и ограничения, и использование "C" в разы все ускорило бы.
Читается по одному пакету.
Вот криворукость
Код: c#
1.
var buff = new byte[len];


зачем тебе каждый раз новый буфер? Чтобы сборщик мусора почаще запускался? Убери эту строчку из цикла, читай в один и тот же буфер.

Думаю использование С тут особо не ускорит.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349117
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, вынос буфера оказал некоторое влияние.
но все заметно изменилось, когда я стал делать друг за другом пачку вызовов, упрощенно показано на рисунке ниже

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
                    var buff1 = new byte[len];
                    var buff2 = new byte[len];
                    var buff3 = new byte[len];
                    var buff4 = new byte[len];
                    while (udpClient.Available > 0 && DoWork)
                    {
                        var buff = new byte[len];
                        ReceivedBytesTotal += (ulong)udpClient.Client.Receive(buff1);//, len, SocketFlags.None);
                        ReceivedBytesTotal += (ulong)udpClient.Client.Receive(buff2);//, len, SocketFlags.None);
                        ReceivedBytesTotal += (ulong)udpClient.Client.Receive(buff3);//, len, SocketFlags.None);
                        ReceivedBytesTotal += (ulong)udpClient.Client.Receive(buff4);//, len, SocketFlags.None);

                        RecevedPacktesTotal+=4;

                        bufferManager.Add(ref buff1, ref len);
                        bufferManager.Add(ref buff2, ref len);
                        bufferManager.Add(ref buff3, ref len);
                        bufferManager.Add(ref buff4, ref len);
                        bufferManager.Add(ref buff5, ref len);

                    }//while


Потери сократились почти в двое. Что тоже не айс, но если считать что теряется до 10% - то это приемлемо.

в планах задумки как оптимизировать bufferManager.Add(ref buff, ref len) и перейти на TCP.

И надо бы где-то откопать как работает копирование в протоколе NFS, через который на том же железе запись через сеть разгоняется до 500мбит/сек. Там наверняка какие-нибудь хитрости.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349157
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это зачем тут?
Код: c#
1.
2.
3.
                   while (udpClient.Available > 0 && DoWork)
                    {
                        var buff = new byte[len];


buff для чего?
Зачем проверка udpClient.Available > 0 ? Определять конец передачи надо где-то в bufferManager.Add() и сбрасывать DoWork. Иначе если передача будет медленно, то ты прочитаешь текущий буфер приема и выпадешь в середине передачи.

От того что ты сделал 4 Receive() и 4 bufferManager.Add() суммарно ничего не поменялось, т.к. все равно последовательно обработка идет. Ещи и проблему создал: если будет три пакета принято, то зависнет в ожидании 4-го. Если уж надо избавиться от bufferManager.Add(), то надо делать это в другом потоке. Пул буферов надо создавать: принял, сунул в очередь на обработку, взял следующий, принял и т.д.
Для тестов скорости выкинь вообще bufferManager.Add() и оставь один Receive(). Так оценишь максимально возможную скорость приема.

PS А эти твои "некоторые" данные это каждый раз новая инфа или слегка измененная старая? Если второе то можно слать только изменения.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349297
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Затестил.
получатель udp_recv
Код: c#
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.
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;

namespace udp_recv {
	class Program {

		static void recv() {
			IPEndPoint ep = null;
			var receiver = new UdpClient(new IPEndPoint(IPAddress.Any, 12345));
			Int32 next = 0, total = 0, lost = 0;;
			Stopwatch sw = new Stopwatch();
			var data = new Byte[65536];
			Console.WriteLine("Wait messages");
			while(true) {
				Int32 size = receiver.Client.Receive(data, data.Length, SocketFlags.None);
				Int32 num = data[0] | data[1] << 8 | data[2] << 16;
				if(num == 0) {
					total = 0;
					next = 1;
					lost = 0;
					sw.Restart();
				} else if (num == 0xFFFFFF) { // последний
					sw.Stop();
					Console.WriteLine($"Receive {total} bytes  Time {sw.ElapsedMilliseconds}  Speed {total / sw.ElapsedMilliseconds} kbyte/sec  Lost {lost} packets");
				} else if(next != num) { // пропуск
					lost += num - next;
					total += size;
					next = num + 1;
				} else {
					total += size;
					next = num + 1;
				}
			}
		}

		static void Main(string[] args) {
			recv();
		}
	}
}

отправитель udp_send
Код: c#
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.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace udp_send {
	class Program {

		static void send(Int32 count, Int32 size, String addr) {
			var sender = new UdpClient();
			var ep = new IPEndPoint(IPAddress.Parse(addr), 12345);
			var data = new Byte[size];
			Console.WriteLine($"Send {count} packets size: {size} Total {count * size} to {addr}");
			var sw = Stopwatch.StartNew();
			for(Int32 i = 0; i < count; i++) {
				data[0] = (Byte) (i & 0xFF);
				data[1] = (Byte) ((i >> 8) & 0xFF);
				data[2] = (Byte) ((i >> 16) & 0xFF);
				sender.Send(data, size, ep);
			}
			data[0] = 0xFF;
			data[1] = 0xFF;
			data[2] = 0xFF;
			sender.Send(data, size, ep);
			Int64 t = sw.ElapsedMilliseconds;
			Console.WriteLine($"Time {t} msec speed {count * size / t} kbyte/sec");
			Thread.Sleep(100);
			sender.Send(data, size, ep);
		}

		static void Main(string[] args) {
			if(args.Length == 0) {
				Console.WriteLine("Usage:\n udp_send [count msg] [size one] [server]\n\n Example:\nudp_send 1000 1472 127.0.0.1\n");
			}
			String addr = "127.0.0.1";
			Int32 count = 1000;
			Int32 size = 1472;
			if(args.Length > 0) {
				count = Int32.Parse(args[0]);
			}
			if(args.Length > 1) {
				size = Int32.Parse(args[1]);
			}
			if(args.Length > 2) {
				addr = args[2];
			}
			send(count, size, addr);
		}
	}
}


Тестил между i5 и i7 по гигабиту. В обе стороны. Скорость 103-105 Мбайт/сек, т.е. чуть быстрее копирования по TCP.

Для теста на одном компе запускай udp_recv, на втором udp_send, результаты смотри на принимающей стороне.
Код: c#
1.
udp_send.exe 100000 1472 192.168.0.1
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349375
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тестить так уж все варианты. Тоже самое по TCP
получатель tcp_recv
Код: c#
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.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace tcp_recv {
	class Program {

		static void recv() {
			IPEndPoint ep = null;
			var receiver = new TcpListener(new IPEndPoint(IPAddress.Any, 12345));
			receiver.Start(1);
			var data = new Byte[65536];
			Console.WriteLine("Wait messages");
			while(true) {
				TcpClient client = receiver.AcceptTcpClient();
				NetworkStream io = client.GetStream();
				Int32 total = 0, read = 1;
				var sw = Stopwatch.StartNew();
				while(read != 0) {
					read = io.Read(data, 0, data.Length);
					total += read;
				}
				client.Close();
				Int64 t = sw.ElapsedMilliseconds;
				Console.WriteLine($"Time {t} msec speed {total / t} kbyte/sec");
			}
		}

		static void Main(string[] args) {
			recv();
		}
	}
}

отправитель tcp_send
Код: c#
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.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace tcp_send {
	class Program {
		static void send(Int32 size, String addr) {
			var sender = new TcpClient(addr, 12345);
			NetworkStream io = sender.GetStream();
			var data = new Byte[65536];
			Console.WriteLine($"Send size: {size} to {addr}");
			Int32 total = size;
			var sw = Stopwatch.StartNew();
			while(size > 0) {
				Int32 send = size > 65536 ? 65536 : size;
				io.Write(data, 0, send);
				size -= send;
			}
			sender.Close();
			Int64 t = sw.ElapsedMilliseconds;
			Console.WriteLine($"Time {t} msec speed {total / t} kbyte/sec");
		}

		static void Main(string[] args) {
			if(args.Length == 0) {
				Console.WriteLine("Usage:\n tcp_send [size] [server]\n\n Example:\ntcp_send 1000000 127.0.0.1\n");
			}
			String addr = "127.0.0.1";
			Int32 size = 10000000;
			if(args.Length > 0) {
				size = Int32.Parse(args[0]);
			}
			if(args.Length > 1) {
				addr = args[1];
			}
			send(size, addr);
		}
	}
}


У меня TCP чуть быстрее получилось. И проц меньше загружает. И букав меньше в коде.

Запускать
Код: c#
1.
tcp_send.exe 100000000 192.168.0.1
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349401
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ожидаемый результат.
Но несмотря на все недостатки UDP у него есть плюсы. Два клиента сидя за НАТами и файрволами могут напрямую обмениваться данными. Это означает быстрое время отклика <1 мс и высокая скорость обмена, до 100 мбит, если оба подключены к одному провайдеру.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349450
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TДва клиента сидя за НАТами и файрволами могут напрямую обмениваться данными ... если оба подключены к одному провайдеру.
далеко не всегда
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349457
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TДва клиента сидя за НАТами и файрволами могут напрямую обмениваться данными ... если оба подключены к одному провайдеру.
далеко не всегда
не всегда, но не далеко
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349710
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТестить так уж все варианты. Тоже самое по TCP
Я смотрю вы прониклись проблемой, и потратили время )))
Дабы усилия не пропали напрасно, я немного адаптировал ваш код, и протестил, результаты в приложенной картинке.

Отправлял всегда по 1Гб, пакеты - 1024 байта (для TCP у Dima T пакеты были много больше, по этому думаю скорость не сопоставима с UDP).
"Средняя скорость загрузки сети" - подглядывалось на диспетчере задач, я думаю, для UDP - это то на что хватает тяму компу который генерирует поток.

Какие будут комментарии?
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349800
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикОтправлял всегда по 1Гб, пакеты - 1024 байта (для TCP у Dima T пакеты были много больше, по этому думаю скорость не сопоставима с UDP).
Что за бред? UDP не умеет передавать большие куски, поэтому надо усложнить жизнь TCP. Зачем?

Твой "большой поток некоторых данных" что из себя представляет на отправителе? Готовый массив или быстропоявляющиеся куски? Если куски, то какого размера?
Надо тестить с условиями приближенными к реальным. Ты же не сферических коней по сети гоняешь, а решаешь конкретную задачу.

По UDP можешь послать пакет размером до 65507 и он придет одним пакетом. Только общая скорость будет ниже, потому что на IP уровне он будет разбит на несколько IP пакетов, а после приемки собран обратно. Поэтому идеальный размер пакета для UDP = MTU - 28 (20 байт заголовок IP + 8 заголовок UDP). MTU изернета 1500 поэтому размер 1500 - 28 = 1472 (если по дороге нет VPN туннелей, их заголовки тоже надо вычитать). Самый маленький MTU я встречал 1372.
Затести разные размеры UDP пакета и посмотри на скорость.

В TCP нет размера пакета, это поток, который при отправке автоматом разбивается на IP пакеты, поэтому чтобы не делать лишних телодвижений и не мешать работать протоколу надо слать сразу как можно больше. Я поставил 65536.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349803
Фотография Смузи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Оба варианта на помойку. Использовать http chunked transfer.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349827
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Затестил TCP по 1024, ничего не поменялось. Результаты те же. Нагрузка на проц чуть приподнялась.
Расказывай что еще означает "немного адаптировал ваш код"
tcp_send по 1024
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
		static void send(Int32 size, String addr) {
			var sender = new TcpClient(addr, 12345);
			NetworkStream io = sender.GetStream();
			var data = new Byte[1024];
			Console.WriteLine($"Send size: {size} (block {data.Length}) to {addr}");
			Int32 total = size;
			var sw = Stopwatch.StartNew();
			while(size > 0) {
				Int32 send = size > data.Length ? data.Length : size;
				io.Write(data, 0, send);
				size -= send;
			}
			sender.Close();
			Int64 t = sw.ElapsedMilliseconds;
			Console.WriteLine($"Time {t} msec speed {total / t} kbyte/sec");
		}


Еще расскажи что за сеть у тебя и сетевое железо. Моделей не надо. Схематично опиши. Я в локалке тестю, через гигабитный свич.
Есть подозрение что через инет гоняешь или какое-то взрослое сетевое оборудование, где баллансировка скорости TCP происходит. UDP поэтому и быстрее в инете, т.к. UDP не баллансируется, а либо пролетает быстро, либо вообще не пролетает.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349886
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TТвой "большой поток некоторых данных" что из себя представляет на отправителе?
Какая-то телеметрия, а как она структурирована и в каком виде будет слаться - я без понятия. Мне сейчас нужно потенциально понять какой для этого ЭВМ нужен, и определить рекомендации каким способом это можно пропихнуть.

Размеры пакетов, протоколы - это уже тюнинг которым будут заниматься потом.
Я допускаю, что сделав блок для TCP пакета побольше - скорость может подтянуться к UDP. Но не это важно. быстрее UDP скорость не прыгнет в итоге. на "слабом" железе - у UDP адские потери, на "нормальном" - потерь почти нет.
Это коррелирует с тормозами которые я получал выше.
Вполне достаточно информации для выводов.
Если брать встраиваемый компьютер без "нормального" сетевого чипа (как неттопы и ноут с которыми я тестил), то для такого потока нужно что-то более мощное чем i3-370M. А там у всех потребляемая мощность близкая, что у i3 что у i5, порядка 15ватт, можно и i5...U выбирать.
Если встраиваемый комп заточен под сетевое применение - то возможно подойдет и атом или селерон, нужно пробовать.

Dima TРасказывай что еще означает "немного адаптировал ваш код"


tcp_send по 1024
Код: c#
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.
        static void udp_send(Int32 countMb, String addr, int port)
        {
            int size = 1024;
            int count = (int)(countMb * 1024.0 * 1024.0 / (double)size);
            Console.WriteLine("Press space to start UDP sending");
            Console.ReadKey();
            var sender = new UdpClient();
            var ep = new IPEndPoint(IPAddress.Parse(addr), port);
            var data = new Byte[size];
            Console.WriteLine("Sending {0} packets, {1} byte per packet (total {2:#0} Mb) to {3}:{4}"
                , count, size, countMb, addr, port);
            var sw = Stopwatch.StartNew();
            for (Int32 i = 0; i < count; i++)
            {
                data[0] = (Byte)(i & 0xFF);
                data[1] = (Byte)((i >> 8) & 0xFF);
                data[2] = (Byte)((i >> 16) & 0xFF);
                sender.Send(data, size, ep);
            }
            data[0] = 0xFF;
            data[1] = 0xFF;
            data[2] = 0xFF;
            sender.Send(data, size, ep);

            Int64 t = sw.ElapsedMilliseconds;

            Console.WriteLine("Done. Time {0:#0.0000} sec speed {1:#0.000} Mb/sec, {2:#0.000} Mbit/sec"
                , t / 1000, (double)countMb / t * 1000.0, (double)countMb / t * 1000.0 * 8);

            Thread.Sleep(100);
            Thread.Sleep(100);
            Thread.Sleep(100);
            sender.Send(data, size, ep);
        }

        static void tcp_send(Int32 countMb, String addr, int port)
        {
            var size = 1024;

            var count = (int)(countMb * 1024.0 * 1024.0 / (double)size);

            Console.WriteLine("Start TCP sending");
            Console.WriteLine("Press space to start TCP sending");
            Console.ReadKey();

            var sender = new TcpClient(addr, port);
            var io = sender.GetStream();
            var data = new byte[size];
            Console.WriteLine("Sending {0} packets per {1} byte (total {2:#0} Mb) to {3}:{4} ..."
                            , count, size, countMb, addr, port);

            var sw = Stopwatch.StartNew();
            while (count > 0)
            {                
                io.Write(data, 0, size);
                count--;
            }
            sender.Close();
            var t = sw.ElapsedMilliseconds;
            Console.WriteLine("Done. Time {0:#0.0000} sec speed {1:#0.000} Mb/sec, {2:#0.000} Mbit/sec"
                , t / 1000, (double)countMb / t * 1000.0, (double)countMb / t * 1000.0 * 8);
        }




Dima TЕще расскажи что за сеть у тебя и сетевое железо. Моделей не надо. Схематично опиши.
Два компа стоят рядом, шнурки по 1,5м, свитч DGS-1005G
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349914
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикДва компа стоят рядом, шнурки по 1,5м, свитч DGS-1005G
Странно. Попробуй свич вообще убрать. Соедини компы проводком напрямую.
IP-шники не забудь прописать, если они извне раздаются.

Как выше писал 19907935 у меня уменьшение до 1024 никак на TCP не повлияло.

Еще вопрос: ты где время смотрел? На отправителе или получателе?

КифирчикЕсли брать встраиваемый компьютер без "нормального" сетевого чипа (как неттопы и ноут с которыми я тестил), то для такого потока нужно что-то более мощное чем i3-370M. А там у всех потребляемая мощность близкая, что у i3 что у i5, порядка 15ватт, можно и i5...U выбирать.
Если встраиваемый комп заточен под сетевое применение - то возможно подойдет и атом или селерон, нужно пробовать.
Загрузку проца еще смотри на нем. Все эти маловаттные процы не рассчитаны на долгую высокую нагрузку, чуть поработает в пиковом режиме и начинает замедляться чтобы в отведенные 15 ватт уложиться.
Что там за сетевухи. Баловался как-то с CubieBoard , неприятным сюрпризом оказалось что выдавить 100 мбит из сетевухи невозможно, 50 примерно было. Точнее на тот девайс передавал, хранилище бэкапов сделал, думал HDD тупит, а оказалось - сетевуха. А ты гигабит хочешь прогнать.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349920
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикDima TТвой "большой поток некоторых данных" что из себя представляет на отправителе?
Какая-то телеметрия, а как она структурирована и в каком виде будет слаться - я без понятия. Мне сейчас нужно потенциально понять какой для этого ЭВМ нужен, и определить рекомендации каким способом это можно пропихнуть.
У тебя этот маломощный девайс на прием или на передачу будет работать?
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349926
Фотография Смузи
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Говорили tcp с udp, говорили...

... так и не договорились


Пришлось все делать адекватному http.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349935
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,
какая-то фантастика
на атоме 330м
- UDP, пакет 1024 байта + увеличил буфер отправки - скорость поднялась с 233 до 324мбит/сек (замеряю по тому что дошло)
- TCP, размер пакета var size = 1024 * 1024 * 2 (вместо size = 1024) - скорость 795мбит... 99м/сек !!!!!

Дело именно в размере пакета для TCP, я проверил, вернул обратно - та же скромная скорость порядка 140мбит/сек

TCP быстрее, и нагрузка на проц в 2 раза ниже чем UDP о_О

на рисунке, график CPU, последний всплеск - TCP, предпоследний UDP

в понедельник сделаю замеры на остальных компах

авторУ тебя этот маломощный девайс на прием или на передачу будет работать?
возможно с него по медленному беспроводному каналу будут что-то загружать (до 10мбит/сек), и если позволят "мощности" данные можно сжимать.

авторЕще вопрос: ты где время смотрел? На отправителе или получателе?
время на получателе.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349960
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КифирчикавторУ тебя этот маломощный девайс на прием или на передачу будет работать?
возможно с него по медленному беспроводному каналу будут что-то загружать (до 10мбит/сек), и если позволят "мощности" данные можно сжимать.
А чего тогда на гигабите тестишь? В свойствах сетевухи выстави 10 мбит. Это же совсем другое. У тебя на гигабите твой неттоп просто захлебывается. На 10мбит думаю запаса хватит каким-нибудь deflаte пожать перед отправкой.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39349965
Кифирчик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКифирчикпропущено...

возможно с него по медленному беспроводному каналу будут что-то загружать (до 10мбит/сек), и если позволят "мощности" данные можно сжимать.
А чего тогда на гигабите тестишь? В свойствах сетевухи выстави 10 мбит. Это же совсем другое. У тебя на гигабите твой неттоп просто захлебывается. На 10мбит думаю запаса хватит каким-нибудь deflаte пожать перед отправкой.

к компу подключено по гигабиту некое оборудование, которое выдает поток до 300мбит/сек и надо его поймать и записать, это основное назначение.
как вторичная функция, удаленно с этого компа могут загружать данные по радиоканалу (дополнительный сетевой интерфейс), скорость которого в лучшем случае 10 мбит/сек. и это дополнительная загрузка диска и проца, которая в прочем не существенна.
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39350012
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчикк компу подключено по гигабиту некое оборудование, которое выдает поток до 300мбит/сек и надо его поймать и записать, это основное назначение.
Документацию смотрел на оборудование? Оно умеет и по TCP и по UDP работать?
...
Рейтинг: 0 / 0
Прокачать большой поток через UDP
    #39350091
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кифирчиккакая-то фантастика
на атоме 330м
- UDP, пакет 1024 байта + увеличил буфер отправки - скорость поднялась с 233 до 324мбит/сек (замеряю по тому что дошло)
Буфер приема пробовал увеличивать? На гигабите он всего 64 кбайта, т.е. 64 твоих пакета. На скорости 324 мбит буфер наполняется за 1.5 мс. Кванты времени выделяемые потоку 10-20 мс, т.е. твой поток может просто потерять данные из-за переключений. Увеличивай буфер минимум до 1 Мб, а лучше до 3-5.
...
Рейтинг: 0 / 0
27 сообщений из 27, показаны все 2 страниц
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Прокачать большой поток через UDP
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]