0 votes
by (250 points)

Hi Team,

I am stuck with this weird error, I need your support to guide me on how to stop the server once running.

  1. Once the serverstart is triggered its working fine.
  2. It I retry to start the server I get below error. Which I believe its normal

    System.Net.Sockets.SocketException: 'Only one usage of each socket address (protocol/network address/port) is normally permitted'

  3. It I try to stop the server, my code doesn't work. Can you guide what I am doing wrong in ServerStop function.

    public void update(SyslogSettings data)
    {
        try
        {
            UpdateSyslogSetting(data);
    
            if (data.syslog_state.Equals(true))
            {
                // create new server instance for every new configuration
                server = new SyslogServer();
    
                int port = Convert.ToInt16(data.port);
                if (data.protocol.Equals("TCP"))
                {
                    var binding = new SyslogBinding(port, SyslogTransportProtocol.Tcp);
                    server.Bind(binding);
                }
                else if (data.protocol.Equals("UDP"))
                {
                    var binding = new SyslogBinding(port, SyslogTransportProtocol.Udp);
                    //binding.UdpBufferSize = 10 * 1024 * 1024;
                    binding.UdpBufferSize = (int)data.buffer_size;
                    server.Bind(binding);
                }
    
                if (data.syslog_state.Equals(true))
                {
                    if (Directory.Exists(contentPath))
                    {
                        string filePath = Path.Combine(contentPath, "syslog-loggin.txt");
                        if (!File.Exists(filePath))
                        {
                            File.Create(filePath).Close();
                        }
                        // start logging to a file
                        server.LogWriter = new Rebex.FileLogWriter(filePath);
                    }
                }
    
                ServerStart();
                Task.Run(() => LogMessage());
            }
            else
            {
                ServerStop();
            }
        }
        catch (Exception e)
        {
            UpdateSyslogSetting(data, e.Message);
            throw e;
        }
    }
    
    
    
    private void ServerStart()
    {
        // on start, create new collection and register MessageReceived event
        messageQueue = new BlockingCollection<SyslogMessageReceivedEventArgs>();
        server.MessageReceived += server_MessageReceived;
        //server.Stop();
        server.Start();
    }
    
    private void ServerStop()
    {
        if (server == null)
            return;
    
        // on stop, mark collection as completed and unregister MessageReceived event
        server.Stop();
        server.MessageReceived -= server_MessageReceived;
        messageQueue.CompleteAdding();
        server = null;
    }
    
    private void server_MessageReceived(object sender, SyslogMessageReceivedEventArgs e)
    {
        messageQueue.Add(e);
    }
    
Applies to: Syslog

1 Answer

0 votes
by (72.7k points)

The provided code looks correct.

The mentioned error System.Net.Sockets.SocketException: 'Only one usage of each socket address (protocol/network address/port) is normally permitted' means that the server is already running and you want to start it again using the same (protocol/network address/port), which is not possible. You have to stop the server fist.

The easiest way to diagnose the issue is to put a breakpoint at line UpdateSyslogSetting(data); and use debugger to step over the whole public void update(SyslogSettings data) and see what is happening.

When the code executes the ServerStop() method, the server should be stopped and the TCP port would be available again.

Also please put breakpoints inside the ServerStart() and ServerStop() methods.
My guess is, that you are somewhere starting the server just after you stop it, so it only seems that the stop does not work.

by (250 points)
Hi Lukas,

        the problem is I am not able to utilize the ServerStop function. My code returns from
private void ServerStop()
{
    if (server == null)
        return;

and never hits the server.Stop();

I am not able to understand how to refer to the running instance to stop it.
if I want to stop the running one I am not able to use serverstop function.
by (72.7k points)
How do you use the application?

If you are having `server == null` it seems that you run the .exe once to start the server, then you run the same .exe for the second time to stop the server?

This will not work of course. You have to invoke the Stop() method on the instance from the first run (the instance used to Start() the server).

If this is your case, you have to add a process synchronization functionality into your application (such as global Mutex, global EventWaitHandle, named Pipe, Memory-mapped File, TCP/IP socket) or pull the syslog_state from DB periodically and react to its changes.

If this is not your case, update your application to keep reference to started server (do not set server = null).
...