Home c# System.NullReferenceException: Object reference does not point to an instance of an object...

System.NullReferenceException: Object reference does not point to an instance of an object – C #

Author

Date

Category

making a small messenger in C # to learn net.sockets;
Made it so that receiving messages was asynchronous, and while receiving them, you could write something.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
    class Program
    {
        //static byte[] buffer = new byte[1024];
        static string str;
        static Socket client;
        static Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        static void Main(string[] args)
        {
            socket.Bind(new IPEndPoint(IPAddress.Any, 25565));
            socket.Listen(5);
            Socket client = socket.Accept();
            Console.WriteLine("New User!!!");
            while (true)
            {
                MainAsync();
                TakeMessage();
            }
        }
        private static async Task TakeMessage() {
            byte[] buffer = new byte[1024];
            Task.Run(() =>  client.Receive(buffer)); //There is a mistake
            Task.Run(() => Console.WriteLine(Encoding.ASCII.GetString(buffer)));
        }
        private static async Task MainAsync()
        {
            Task.Run(() => str = Console.ReadLine());
            Task.Run(()=> command(str));
        }
        private static async Task NewUser()
        {
            //Task.Run(()=>)
        }
        private static void command(string com){
            if(com == "close")
            {
                client.Shutdown(SocketShutdown.Both);
            }
        }
    }
}

But on the 32nd line the error “System.NullReferenceException:” Object reference does not point to an object instance. ”


Answer 1, authority 100%

You have no clientvariable assigned. As I understand it, you need 2 sockets, one for sending messages, one for receiving. So, you initialized one, and the second did not. (By the way, do you really need two?)

At the same time, Microsoft recommends here :

If you are building a relatively simple application that does not require maximum performance, consider using TcpClient, TcpListenerand UdpClient. These classes provide a simpler and more convenient interface for interacting with the Socket.

But this is only part of the problem. You are strangely using asynchrony, which you don’t really need. Basically you just need 2 streams, one for receiving messages, the other for transmitting, and so that they work simultaneously.

I wrote a short example, stripping away all the networking code, and leaving only the skeleton to demonstrate a template with two tasks running at the same time.

I will use CancellationTokento control the interruption of tasks. Study it, it can come in handy in many places. It can also be passed to all sorts of standard asynchronous methods.

// asynchronousMain, note
static async Task Main(string[] args)
{
    using (CancellationTokenSource cts = new CancellationTokenSource())
    {
        List<Task> loops = new List<Task>();
        loops.Add(Task.Run(() => ReceiveMessageLoop(cts)));
        loops.Add(Task.Run(() => SendMessageLoop(cts)));
        await Task.WhenAll(loops);
    }
    Console.WriteLine("Shutdown");
    Console.ReadKey();
}
private static void ReceiveMessageLoop(CancellationTokenSource cts)
{
    while (true)
    {
        Console.WriteLine("ReceiveMessageLoop");
        Thread.Sleep(5000);
        if (cts.Token.IsCancellationRequested)
        {
            break;
        }
    }
    Console.WriteLine("ReceiveMessageLoop exit");
}
private static void SendMessageLoop(CancellationTokenSource cts)
{
    while (true)
    {
        Console.Write("Command: ");
        string command = Console.ReadLine();
        if (command == "exit")
        {
            cts.Cancel();
        }
        if (cts.Token.IsCancellationRequested)
        {
            break;
        }
    }
    Console.WriteLine("SendMessageLoop exit");
}

And here’s the proof that asynchrony is not really needed, there will be no difference in the behavior of the application.

// normal synchronousMain
static void Main(string[] args)
{
    using (CancellationTokenSource cts = new CancellationTokenSource())
    {
        List<Task> loops = new List<Task>();
        loops.Add(Task.Run(() => ReceiveMessageLoop(cts)));
        loops.Add(Task.Run(() => SendMessageLoop(cts)));
        Task.WaitAll(loops.ToArray());
    }
    Console.WriteLine("Shutdown");
    Console.ReadKey();
}

And for the implementation of the network part using Socket, if you really really want to, and even with asynchrony, see examples in the documentation: Client , Server .

Another note: asyncwithout awaitinside does not make any sense and has no effect, and the opposite is generally impossible. 🙂

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions