Hello ! I started writing a simple TCP server and faced a very curious situation. I was advised to use an interesting method, but I have never used it before and I don’t know how it works and how it is called too, but the fact is that you can call the whole class conditionally as a function of this type new Function ()

In general, during initialization, your function is executed and immediately IDisposable kills it.

I have a class Session in it I listen to the client on TCP after I received a packet from it, the received buffer array is sent to the Handler function

with each new client, I bring it to ClientsManager in this case, I create many copies of the Session for each client

using System; using System.Net.Sockets; namespace server { class Session : IDisposable { private byte[] buffer; private Socket socket { get; set; } public Session(Socket socket) { this.socket = socket; socket.ReceiveTimeout = 1000; ClientsManager.online++; buffer = new byte[2]; socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, End2Bytes, null); } private void End2Bytes(IAsyncResult result) { try { if (socket.EndReceive(result) >= 2) { var length = BitConverter.ToUInt16(buffer, 0); buffer = new byte[length]; socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, EndReadBytes, null); } else { Disconnect(); // Отключаем клиента с не понятными пакетами Console.WriteLine("socket.EndReceive(result) < 2"); // Пакеты меньше 2 байт } } catch (Exception e) // Удаленный хост принудительно разорвал существующее подключение { Console.WriteLine(e); } } private void EndReadBytes(IAsyncResult result) { try { if (socket.EndReceive(result) == buffer.Length && buffer.Length >= 2) new Handler(buffer); // было Handler(buffer); buffer = new byte[2]; socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, End2Bytes, null); } catch (Exception e) // Удаленный хост разорвал существующее подключение { Console.WriteLine(e); } } private void Disconnect() { socket.BeginDisconnect(false, EndDisconnect, null); } private void EndDisconnect(IAsyncResult result) { socket.EndDisconnect(result); socket.Disconnect(false); ClientsManager.getInstance().clients.Remove(this); ClientsManager.online--; Dispose(); } public void Dispose() { socket = null; buffer = null; } ~Session() { Dispose(); } //private void Handler(byte[] buffer) // Перенесён в класс Handler //{ //} } } 

Initially, I kept the Handler () function in the Session class and advised me to bring the Handler into a separate class, say why are you hammering the memory with the same Handler? Imagine - how many clients are so many copies of the Handler (Handler'a)

bring it to a separate class and call it not Handler (buffer); and new Handler (buffer); Well, in the Handler class write this:

 using System.IO; namespace server { class Handler { public Handler(byte[] buffer) { using (var br = new BinaryReader(new MemoryStream(buffer))) { var opcode = br.ReadUInt16(); switch (opcode) { case 0000: { break; } // Disconnect case 0001: { break; } // Version case 0002: { break; } // Check Login & Password // Answer ID default: { Console.WriteLine("Unknown OpCode : " + opcode ) ; break; } } } } } } 

In general, the actual question: when calling the command new Handler (buffer), I call a function from another class? or is a copy created for each session? by essence, this is a very large load on the server when there are 100 clients, each has its own session, and each session creates a new Handler each time to process 1 packet and about 60 packets arrive from one client in 1 second or it just calls as a function ?

it would be possible to create a public static class in it public static void Get (buffer) and call it in a session just like Handler.Get (buffer)

but then it seems to me that there will be a clogged flow, that is, until the session for example player A launches Handler.Get (buffer), at this time, session B of the session starts and waits until Handler.Get (buffer) is released from player A

or am I mistaken? what do you advise ? and explain what new Function () is, how does it work? or is it in fact the same thing that a static function in another class or when calling Handler.Get (buffer) will also create a copy? then which one is better for performance?

and what is better to use, as per more productive?

1) the handler is straight in the session class

2) create a new class and process it during initialization?

3) or make a static function in

other class and call it from each session?

  • 2
    Nothing is clear. By the way, your finalizer is completely useless. - Pavel Mayorov

1 answer 1

You have been advised of something strange (well, or you have not understood the advice).

Methods do not "occupy memory" inside the class. Those. your

 private void Handler(byte[] buffer) // Перенесён в класс Handler { } 

will not take "additional memory inside each Session ". The code itself is common to all Session objects. Memory for each instance occupy only the class field. Here are your Session class fields:

 private byte[] buffer; private Socket socket { get; set; } 

But allocating a Handler to a separate class, and even creating it for each call (via new) really creates a new Handler for each call to a new Handler, eating away at the same time the memory (though not for long, and slightly). Those. the second option is worse (slightly) in memory than the first.