I make a kind of RPC. Interested in the exchange rate for TCP / IP

Now the exchange rate of the order of 20 bytes is 2000 calls per second. But I feel that the speed can be more. Such a client

private BinaryReader SendMessage(MemoryStream stream) { using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { client.Connect(IpEndpoint); using (var ns = new NetworkStream(client)) { stream.Position = 0; ns.Write(BitConverter.GetBytes((Int32)stream.Length), 0, 4); stream.CopyTo(ns); using (var br = new BinaryReader(ns)) { var streamSize = br.ReadInt32(); var res = br.ReadBytes(streamSize); var ms = new MemoryStream(res); ms.Position = 0; return new BinaryReader(ms); } } } 

And server

  public void Open(int НомерПорта = 6891, int КоличествоСлушателей = 1) { IsClosed = false; IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Any, НомерПорта); Server = new TcpListener(ipEndpoint); Server.Start(); // Создадим задачи для прослушивания порта //При подключении клиента запустим метод ОбработкаСоединения // Подсмотрено здесь https://github.com/imatitya/netcorersi/blob/master/src/NETCoreRemoveServices.Core/Hosting/TcpServerListener.cs for (int i = 0; i < КоличествоСлушателей; i++) Server.AcceptTcpClientAsync().ContinueWith(OnConnect); } // Метод для обработки сообщения от клиента private void OnConnect(Task<TcpClient> task) { if (task.IsFaulted || task.IsCanceled) { // Скорее всего вызвано Server.Stop(); return; } // Получим клиента TcpClient client = task.Result; // И вызовем метод для обработки данных // ExecuteMethod(client); // Если Server не закрыт то запускаем нового слушателя if (!IsClosed) Server.AcceptTcpClientAsync().ContinueWith(OnConnect); } static void SetResult(MemoryStream ms, NetworkStream ns) { ms.Position = 0; ns.Write(BitConverter.GetBytes((Int32)ms.Length), 0, 4); ms.CopyTo(ns); ns.Flush(); } private void RunMethod(NetworkStream ns, MemoryStream ms) { using (BinaryReader br = new BinaryReader(ms)) { var msRes = new MemoryStream(); using(BinaryWriter bw= new BinaryWriter(msRes)) { var cm = (CallMethod)br.ReadByte(); if (cm == CallMethod.CallFunc) { CallAsFunc(br, bw); } bw.Flush(); SetResult(msRes, ns); } } } private void ExecuteMethod(TcpClient client) { using (NetworkStream ns = client.GetStream()) { // Получим данные с клиента и на основании этих данных //Создадим ДанныеДляКлиета1 котрый кроме данных содержит //TcpClient для отправки ответа using (var br = new BinaryReader(ns)) { var streamSize = br.ReadInt32(); var res = br.ReadBytes(streamSize); var ms = new MemoryStream(res); ms.Position = 0; RunMethod(ns, ms); } } } 

Call through DinamicObject

 var wrap = Client.AutoWrapClient.GetProxy("127.0.0.1", 6891); int res = wrap.ReturnParam(3); Console.WriteLine(res); string str = wrap.ReturnParam("Hello"); Console.WriteLine(str); var Тестовый = wrap.Тип("TestDllForCoreClr.Тестовый", "TestDll"); var TO = wrap.New(Тестовый,"Свойство из Конструктора"); int rs = TO.ПолучитьЧисло(89); count = 0; stopWatch.Restart(); for (int i = 0; i < 10000; i++) { count += TO.ПолучитьЧисло(i); } stopWatch.Stop(); 
  • Well, for starters, compare at least. 1. Take the file 2-10 Gb - copy (to the computer with which the connection is on "RPC"), you get the number of byte-seconds. 2. Take your calls, calculate the length of your packets, add up (if the packets are short, add the TCP / IP header length), and get the number of bytes. Notch n-seconds - convert the number to byte seconds. Then you can make an assessment. Maybe you have everything ok. - nick_n_a
  • I want to know how much speed for a local computer is normal, for those who are closely involved in this. - Serginio
  • one
    The tcp rate is not measured in calls per second. It is measured in bytes per second. If the packets are very small, the speed will be low, even with a good network. If the server and client are on the same machine, then the speed is usually up to 6 gigabytes per second (peak). In LAN, either 50-100 mb / s, or 500-1000 mb / s (depending on the type of locale and settings). With firewall enabled (and incorrectly configured), speed even on LAN can drop to 0 :) - KoVadim
  • It's clear. In this case, we are talking about an RPC of the order of 100-1000 bytes on the parameters and the name of the method - Serginio
  • in this case, you need to take into account that at this time the time for processing the request on the server is included. And if it is large, then the network speed does not matter. - KoVadim

1 answer 1

Made a speed test with a constant connection and a connection for each request

 using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; using System.Threading.Tasks; using System.IO; using System.Net.NetworkInformation; using System.Diagnostics; using System.Linq; namespace ClientRPC { public class TCPClientConnector { TcpListener Server; // Будем записывать ошибки в файл // Нужно прописать в зависимости "System.Diagnostics.TextWriterTraceListener" // Файл будет рядом с этой DLL // Устанавливаем флаг при закрытии bool IsClosed = false; // Клиент для отпраки сообщений на сервер public TCPClientConnector() { } // Откроем порт и количество слушющих задач которое обычно равно подсоединенным устройствам // Нужно учитывть, что 1С обрабатывает все события последовательно ставя события в очередь public void Open(int Port = 6892, int CountListener = 5) { IsClosed = false; IPEndPoint ipEndpoint = new IPEndPoint(IPAddress.Any, Port); Server = new TcpListener(ipEndpoint); Server.Start(); // Создадим задачи для прослушивания порта //При подключении клиента запустим метод ОбработкаСоединения // Подсмотрено здесь https://github.com/imatitya/netcorersi/blob/master/src/NETCoreRemoveServices.Core/Hosting/TcpServerListener.cs for (int i = 0; i < CountListener; i++) Server.AcceptTcpClientAsync().ContinueWith(OnConnect); } // Метод для обработки сообщения от клиента private void OnConnect(Task<TcpClient> task) { if (task.IsFaulted || task.IsCanceled) { // Скорее всего вызвано Server.Stop(); return; } // Получим клиента TcpClient client = task.Result; // И вызовем метод для обработки данных // ExecuteMethod(client); // Соединение на каждый запрос //ExecuteMethod2(client);// Постоянное соединение // Если Server не закрыт то запускаем нового слушателя if (!IsClosed) Server.AcceptTcpClientAsync().ContinueWith(OnConnect); } private static byte[] GetByteArrayFromStream(NetworkStream ns, int Lingth) { byte[] result = new byte[Lingth]; int ReadBytes = 0; while (Lingth > ReadBytes) { ReadBytes += ns.Read(result, ReadBytes, Lingth - ReadBytes); } return result; } // Соединение на каждый запрос private void ExecuteMethod(TcpClient client) { // client.Client.NoDelay = true; using (NetworkStream ns = client.GetStream()) { // Получим данные с клиента и на основании этих данных //Создадим ДанныеДляКлиета1С котрый кроме данных содержит //TcpClient для отправки ответа using (var br = new BinaryReader(ns)) { var streamSize = br.ReadInt32(); var res = br.ReadBytes(streamSize); res[0] = 4; ns.Write(BitConverter.GetBytes(streamSize), 0, 4); ns.Write(res, 0, streamSize); } } } // Постоянное соединение private void ExecuteMethod2(TcpClient client) { // client.Client.NoDelay = true; NetworkStream ns = client.GetStream(); var buffer = new byte[4]; while (true) { buffer = GetByteArrayFromStream(ns, 4); var streamSize = BitConverter.ToInt32(buffer, 0); var res = GetByteArrayFromStream(ns, streamSize); res[0] = 4; ns.Write(BitConverter.GetBytes(streamSize), 0, 4); ns.Write(res, 0, res.Length); } } } } 

And customer

 using System; using System.IO; using System.Net.Sockets; using System.Net; namespace TestSpeedTcpClient { class Program { static int repeatCount = 10000; static byte[] GetTestArray() { var res = new byte[40]; for (byte i = 0; i < 40; i++) res[i] = i; return res; } // Запрос с подключением и разрывом соединения static byte[] SendMessage(byte[] ms, IPEndPoint IpEndpoint) { using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { client.Connect(IpEndpoint); // client.NoDelay = true; using (var ns = new NetworkStream(client)) { ns.Write(BitConverter.GetBytes(ms.Length), 0, 4); ns.Write(ms, 0, ms.Length); using (var br = new BinaryReader(ns)) { var streamSize = br.ReadInt32(); var res = br.ReadBytes(streamSize); return res; } } } } // Запрос с постоянным соединением static byte[] SendMessage2(byte[] ms, NetworkStream ns) { ns.Write(BitConverter.GetBytes(ms.Length), 0, 4); ns.Write(ms, 0, ms.Length); var buffer = new byte[4]; ns.Read(buffer, 0, 4); var streamSize = BitConverter.ToInt32(buffer, 0); var res = new byte[streamSize]; ns.Read(res, 0, streamSize); return res; } // Тест скорости с постоянным соединением static int TestPermanentConnection() { int count = 0; var IpEndpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6892); var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.Connect(IpEndpoint); var ns = new NetworkStream(client); var res = GetTestArray(); for (int i = 0; i < repeatCount; i++) { res = SendMessage2(res, ns); count += res[0]; } return count; } // Тест скорости с подключением и разрывом соединения static int TestOneConnection() { int count = 0; var IpEndpoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6892); var res = GetTestArray(); for (int i = 0; i < repeatCount; i++) { res = SendMessage(res, IpEndpoint); count += res[0]; } return count; } static void Main(string[] args) { Console.WriteLine("Hello Client!"); var stopWatch = new System.Diagnostics.Stopwatch(); stopWatch.Start(); var res = TestOneConnection(); // var res = TestPermanentConnection(); stopWatch.Stop(); var ts = stopWatch.Elapsed; var elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10, 0); Console.WriteLine(res); Console.WriteLine(elapsedTime); Console.ReadKey(); } } } 

Exchange with a constant connection is much higher and is about 15,000 requests per second