How to keep the connection open in C# when sending strings from a Node.js application to a C# application

Andreas ss 726 Reputation points
2021-03-13T03:08:29.903+00:00

Hello!

I am creating a server and client between a Winform application and a Node.js application.

I then want to send string from Node.js to the Winform application.
The below code does work but I have 2 questions.

Question 1:
The "listenserver" function is started in the "Form1_Load" event. Now when I start the Node.js application, I do send
the string: "Hello C# server I am nodeJS"
This works well and the string is shown in the messagebox in the "listenserver".

My question here is that the function finishes here and will not catch the next message: "Hello C# server I am nodeJS again".
How will I put this "listenserver" in code so it is always open for messages from Node.js?

Question 2:
As seen I have put the below buffer:
var buffer = new byte[1000];
This means that it will only be able to show a string with a maximum length of 1000 chars. Now the string sent by Node.js can be anything between
1 to 1500000 or even more in length. How will I write that buffer. If I put a very large number like: 50000000 in the buffer which will be
much more than the maximum that will ever be received.
Is that okay to do or will this slow down the sending of the strings?

//C# code
        private void Form1_Load(object sender, EventArgs e)
        {
            Thread thread = new Thread(listenserver); thread.IsBackground = true; thread.Start();
        }
        void listenserver()
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 3000));
            socket.Listen(0);
            var client = socket.Accept();
            var buffer = new byte[1000];
            int rec = client.Receive(buffer, 0, buffer.Length, 0);
            Array.Resize(ref buffer, rec);
            MessageBox.Show(Encoding.UTF8.GetString(buffer));
            client.Close();
            socket.Close();
        }


//Node.js code
var net = require("net");
var client = new net.Socket();

client.connect(3000, "127.0.0.1", function(){
    console.log("Connected");
    client.write("Hello C# server I am nodeJS");
    client.write("Hello C# server I am nodeJS again");
})
client.on('close', function(){
    console.log("Connection closed");
})
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,094 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Alberto Poblacion 1,551 Reputation points
    2021-03-13T11:49:50.09+00:00

    For question 1: Add an infinite loop in the method that receives data:

    while (true) { your code here }

    This will keep it always running and it will continue to receive messages. It will not block your main program because you are running it in a separate thread. And it will be terminated automatically when you close your program because you set the Thread to IsBackground=true.

    However, note that there is something that may give you trouble: This appears to be a Winforms Application given that you have a Form_Load. This type of application does not allow accessing the screen from a different thread, but you are using a messagebox in your Thread. To do this correctly, you need to marshall execution to the main thread before displaying the message box. Look up in the documentation "Control.Invoke". The Invoke method of any control (including the Form itself) allows you to bring execution momentarily to the main thread.

    For question 2: You can allocate a large buffer if you wish. It will not slow down anything, but it will allocate a large amount of memory to your program. If you are not using all the memory, the operating system will swap out to disk any parts that are not currently in use, if the system starts running low on memory.

    However, there is a better way, although it takes more programming effort. When you call client.Receive, you pass the Length of the buffer to the Receive method, and the method returns the number of bytes that it actually read. If it tells you that it read less bytes than the buffer size, you are done. But if it tells you that it used the whole buffer, there might be more bytes incoming. In this case, you repeat in a loop and call Receive again to get the next buffer-load of characters. Repeat until the number received is less than the size of the buffer. In this way, you can receive a long message split into small pieces, each of them equal to the buffer length.
    A warning about this: If you are truly using UTF8, as appears to be the case from your call to UTF8.GetString, be aware that some characters occupy more than one byte when encoded in UTF8. If you are receiving your message split into pieces, make sure that you don´t try to do the GetString on one of the individual pieces, because this will fail if one of the multibyte characters happens to be split in between two buffers.