Search code examples
c#socketssocketserver

Is it bad Ju-ju that the port is still being listened to after my app shuts down?


My app listens on a certain port for socket messages. I can see that it is LISTENING via "netstat -a" at the command line.

When I shut the app down, the machine is still listening on that port when I re-run "netstat -a"

Is this a problem?

It seems like maybe it is, as when I subsequently start the app again, it crashes ignominiously.

How can I cause the listening to cease?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;

namespace testSocketSendAndReceive_Nutshell
{
    public partial class Form1 : Form
    {
        string sJerrysIPAddr = "10.24.93.110";
        string sMyIPAddr = "10.24.93.128";
        string sThisAppFileName = string.Empty;
        bool bThisInstanceFunctionsAsServer = false;

        internal static Form1 MainSocketPairForm = null;

        public Form1()
        {
            InitializeComponent();
            MainSocketPairForm = this;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            sThisAppFileName = System.Diagnostics.Process.GetCurrentProcess().ProcessName; // This provides just the app name, appending ".vshost" but NOT ".exe" (testSocketSendAndReceive_Nutshell.vshost)
            lblFileName.Text = sThisAppFileName;

            // Client and Server code are here combined in one app; however, we want each instance to run as
            // just one or the other, so (the .exe functioning as a Server should be renamed with the subString
            // "Server" somewhere in the filename):
            bThisInstanceFunctionsAsServer = sThisAppFileName.Contains("Server");
            if (bThisInstanceFunctionsAsServer)
            {
                new Thread(Server).Start();       // Run server method concurrently.
                Thread.Sleep(500);                // Give server time to start.
            }
            btnSendMsg.Visible = !bThisInstanceFunctionsAsServer;
            textBox1.Visible = !bThisInstanceFunctionsAsServer;
        }

        static void Client()
        {
            using (TcpClient client = new TcpClient(Form1.MainSocketPairForm.sJerrysIPAddr, 51111)) // err here second time around
            using (NetworkStream n = client.GetStream())
            {
                BinaryWriter w = new BinaryWriter(n);
                w.Write(Form1.MainSocketPairForm.textBox1.Text.ToString());
                w.Flush();
                Form1.MainSocketPairForm.label1.Text = new BinaryReader(n).ReadString();
            }
        }

        static void Server()     
        {
            TcpListener listener = new TcpListener(IPAddress.Any, 51111);
            listener.Start();
            var shouldExit = false;
            while (!shouldExit)
                using (TcpClient c = listener.AcceptTcpClient())
                {
                    using (NetworkStream n = c.GetStream())
                    {
                        string msg = new BinaryReader(n).ReadString();
                        if (msg == "exit")
                            // Client told us to exit... 
                            shouldExit = true;
                        BinaryWriter w = new BinaryWriter(n);
                        w.Write(msg + " back atcha!");
                        w.Flush(); // Must call Flush because we're not disposing the writer. 
                    }
                }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Client();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Close();
        }
    }
}

Solution

  • Your application is probably not actually exiting (check task manager "Processes" tab for your .exe).

    You are probably trying to close the application by just closing the command window. Because your Server thread is not a background thread, it will just keep running. Try this guy in Form_Load:

    if (bThisInstanceFunctionsAsServer)
            {
                var serverThread = new Thread(Server);
                serverThread.IsBackground = true; // Make sure the server thread doesn't keep the app running in the background
                serverThread.Start();       // Run server method concurrently.
                Thread.Sleep(500);                // Give server time to start.
            }