0

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();
        }
    }
}
B. Clay Shannon-B. Crow Raven
  • 8,547
  • 144
  • 472
  • 862
  • what Port are you listening on..for example.. and when it crashes how are you so sure it's becasue of the port.. can you paste an example of the code where it sometimes crashes.. – MethodMan Jan 06 '12 at 22:43
  • Yes, it is a problem and for the reason you mentioned. When you start the app a 2nd time, that ip/port is already in use. Are you calling Dispose(), Close(), and any other cleanup method that you should? – user1231231412 Jan 06 '12 at 22:45
  • Can you post some code so we can help you determine the cause? – M.Babcock Jan 06 '12 at 22:56
  • 1
    Is your application actually terminating? If the process is still hanging around (you can check with Task Manager), you likely have a blocked thread hanging up termination of your app. – Dan Bryant Jan 07 '12 at 00:01
  • "It seems like maybe it is, as when I subsequently start the app again, it crashes ignominiously." What have you done to debug where in your code it crashes? Sounds like there maybe multiple bugs here. 1) socket/process not shutting down correctly. And 2) A general failure to initialize and bind a socket results in an exception or program crash. – selbie Jan 07 '12 at 01:14
  • To answer the comments above: I'm listening on port 51111 (a "random" port that was being used in the sample code I started with. I don't know whether I should call Dispose() or Close() or...? and where - in the FormClosing() event, or...? I added the code to the original post now. App terminating - I just checked Task Manager, and the process is still "live" although it's been 2.5 days since I last ran it. – B. Clay Shannon-B. Crow Raven Jan 09 '12 at 16:03
  • I made a blog post out of the finished example: http://warbler.posterous.com/simplest-dual-purpose-c-socket-sendreceive-ex – B. Clay Shannon-B. Crow Raven Jan 09 '12 at 17:43

1 Answers1

3

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.
        }
Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • Always question your assumptions. That is what I most like about this answer. When things are failing and everything seems right, the something you are assuming is happening or is set correctly, or otherwise is as it should be - isn't. – Pete Mancini Jan 09 '12 at 16:17