Simple TCP Send Receive with multithreading c#
There are several things that can be improved on the current code. 

Starting by the listener, if you want to create a TcpListener you can use 

var tcpListener = new TcpListener(IPAddress.Loopback, 20000); or 
var tcpListener = new TcpListener(IPAddress.Any, 20000);


The Main method looks a bit like spaghetti code. 
Specially because you keep alternating statements between things you need for the TcpListener and things that you need for TcpClient.

One possible thing you could do about this is to let StartTcpListenerThread create the TcpListener himself. 
Same goes for StartTcpSendingThread.


  var senderPort = listenerPort + 2;


You don't have to be explicit about the port the client should use, since the operating system 
will attribute a port dynamically as long as you use TcpClient tcpClient = new TcpClient("localhost", 20000);


  while (true)    {   }


This is great, if you want to increase your power bill by putting your CPU usage on 100. 
If you don't want to do that however, you can use Console.ReadLine(); or Thread.Sleep(Timeout.Infinite);

If possible you should also be consistent on whatever you use var or not.

Here is the code with the things I stated applied to it.

public static readonly int Port = 20000;

public static void Main()
{
    StartTcpListenerThread();
    Thread.Sleep(300);
    StartTcpSendingThread();
    Console.ReadLine();
}

static void StartTcpListenerThread()
{
    var tcpListener = new TcpListener(IPAddress.Any, Port);
    tcpListener.Start();
    Thread tcpListenerThread = new Thread(() =&gt;
    {
        while (true)
        {
            try
            {
                var bytes = new byte[1024];
                var currentConnection = tcpListener.AcceptTcpClient();
                var stream = currentConnection.GetStream();
                var numBytesReadFromStream = stream.Read(bytes, 0, bytes.Length);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }
    });
    tcpListenerThread.Start();
}

static void StartTcpSendingThread()
{
    var tcpSendingThread = new Thread(() =&gt;
    {
        var tcpClient = new TcpClient("localhost", Port);
        while (true)
        {
            try
            {
                tcpClient.Client.Send(new byte[] { 1, 2, 8 });
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    });
    tcpSendingThread.Start();
}


Regarding your question about exceptions it seems reasonable to me, to catch the exception and display what is wrong to the console. Most of the time this will be due to some network issue and there isn't much you can do on those scenarios. Keeping the listener listening requests may or may not be a good decision but I would say it's at least a somewhat decent decision for a first approach.