Packet Scout (show traffic on specified port) I've just made a github repository for a simple packet scout in C#. It is my first time using C# (other than Neoaxis 3D engine logic) since I am more familiar with C#. Below is the main bulk of the code that I'd like to improve. You can see all of the code here. If you have any suggestions please share them.

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.Net.Sockets;
using System.Net;

namespace Packet_Scout 
{
    public partial class Form1 : Form {
        private const string endl = "\n";
        private UdpClient socket;
        private bool listening = false;
        private static string buff = "";

        public Form1() {
            InitializeComponent();
        }

        private void downloadbuffer() {
            rblog.Text += buff;
            buff = "";
        }

        private void btnstart_Click(object sender, EventArgs e) {
            if (!listening) {
                rblog.Text = "";
                socket = new UdpClient((int)ndoor.Value);
                tmbuf.Start();
                bgw.RunWorkerAsync();
                btnstart.Text = "Stop";
                listening = true;
            } else {
                tmbuf.Stop();
                downloadbuffer();
                bgw.CancelAsync();
                socket.Close();
                rblog.Text += "Stopped!";
                listening = false;
                btnstart.Text = "Start";
            }
        }

        private void bgw_DoWork(object sender, DoWorkEventArgs e) {
            buff = "Listening on port " + ndoor.Value + endl;

            while (socket != null) {
                if (socket.Available &gt; 0) {
                    IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 0);
                    Byte[] recvbytes= socket.Receive(ref ipep);

                    buff += "Client (" + ipep.Address + ":" + ipep.Port + "): ";
                    foreach (Byte b in recvbytes) buff += b.ToString() + " ";
                    buff += endl;
                }
            }
        }

        private void tmbuf_Tick(object sender, EventArgs e) {
            downloadbuffer();
        }
    }
}
Naming  

Methods should be named using PascalCase casing and should reflect by its name what the responsibility of the method is. So instead of downloadbuffer() a more descriptive name would be AppendToRichtextBox() or something similiar.  

Talking about responisibilties, a class should usually have only one responsibility, so you should separate the UI related code and the listening code into separate classes.  



BackgroundWorker


The BackgroundWorker has an event to report the current progress, so no timer is needed.  
The call to CancelAsync() isn't working like you guess it is.  


  CancelAsync submits a request to terminate the pending background operation and sets the CancellationPending property to true.
  
  When you call CancelAsync, your worker method has an opportunity to stop its execution and exit. The worker code should periodically check the CancellationPending property to see if it has been set to true.  


Now you will say, but it stops the worker. This is only partial true, because after the said call you are closing the socket which will lead to a ObjectDisposedException at retrieving the socket.Available property.
This exception will be passed to the RunWorkerCompleted eventhandler see the DoWork() event documentation  


  If the operation raises an exception that your code does not handle, the BackgroundWorker catches the exception and passes it into the RunWorkerCompleted event handler, where it is exposed as the Error property of System.ComponentModel.RunWorkerCompletedEventArgs. If you are running under the Visual Studio debugger, the debugger will break at the point in the DoWork event handler where the unhandled exception was raised. If you have more than one BackgroundWorker, you should not reference any of them directly, as this would couple your DoWork event handler to a specific instance of BackgroundWorker. Instead, you should access your BackgroundWorker by casting the sender parameter in your DoWork event handler.





Instead of adding to the static buffer variable I would suggest to use the ReportProgress() event and instead of using the string variable you should use a StringBuilder object and passing the built string to the event. By doing so you omit the fact that for each string concatination a new string is created because strings in .NET are immutable.  

Like  

private void bgw_DoWork(object sender, DoWorkEventArgs e) {
    StringBuilder sb = new StringBuilder();

    sb.Append("Listening on port ")
      .Append(ndoor.Value)
      .Append(endl);

    while (socket != null) {
        if (socket.Available &gt; 0) {
            IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 0);
            Byte[] recvbytes= socket.Receive(ref ipep);

            sb.Append("Client (")
              .Append(ipep.Address) 
              .Append(":")
              .Append(ipep.Port)
              .Append("): ");

            foreach (Byte b in recvbytes)
            {
                sb.Append(b.ToString())
                  .Append(" ");
            }
            sb.Append(endl);

            bgw.ReportProgress(0, sb.ToString());
            sb.Length = 0;
        }
    }

    private void AppendToRichtextBox(string value)
    {
        rblog.AppendText(value);
        rblog.ScrollToCaret();
    }  

    private void bgw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        AppendToRichtextBox(e.UserState.ToString());
    }


because the Append() method of the StringBuilder is returning a StringBuilder you can fluently call this method like sb.Append("first ").Append("and second !");.  

If you want to add a carriage return + new line you can simply call one of the overloaded AppendLine() methods.  

You can also use the var type if the right hand side of the assignment makes the type obvious 


  Beginning in Visual C# 3.0, variables that are declared at method scope can have an implicit type var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type.


Like  

var sb = new StringBuilder();