NullReferenceException в C # при работе с потоками? - PullRequest
1 голос
/ 26 сентября 2011

Итак, я довольно новичок во всем этом сетевом программировании, и у меня есть несколько вопросов ...

Я создаю клиент-серверное приложение чата, в котором сервер работает, клиент (ы) подключаются к серверу, а затем, когда клиент отправляет сообщение на сервер, сервер передает его все клиенты. Сервер является консольным приложением, а клиент - приложением Windows Form.

Ошибка, которую я получаю, находится в моем клиенте, в самом верху формы у меня есть текстовое поле для ввода имени пользователя и кнопка «отправить» его и подключиться к серверу с этим именем пользователя.

В любом случае, это мой код подключения кнопки:

    private void btnConnect_Click(object sender, EventArgs e)
    {
        readData = "Connecting to chat server...";
        msg();

        try
        {
            sck_client.Connect("127.0.0.1", 8888);
            sw = new StreamWriter(sck_client.GetStream());
            string toSend = txtUsername.Text;

            sw.Write(toSend);
            sw.Flush();

            chatThread = new Thread(GetMessages);
            chatThread.Start();
        }
        catch (Exception ex)
        {
            readData = ex.ToString(); 
            msg();
        }
    }

msg () довольно просто берет значение в readData и выводит его на экран (в richtextbox). sw является потоковым писателем, который был объявлен публично вне метода, так же как sck_client (TcpClient) и chatThread (поток).

По сути, проблема в том, что когда я запускаю свою программу и пытаюсь подключиться, она выдает Exception ex, как будто она не может подключиться. Выдает исключение NullReferenceException с текстом:

System.NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта. на Chat_Client.Main.btnConnect_Click (Отправитель объекта, EventArgs e) в filepath \ Chat_Client \ Main.cs: line36

Это происходит, даже когда мой сервер работает и прослушивает порт 8888. Итак, что я должен сделать, чтобы это исправить?

Если вам понадобится больше моего кода для решения проблемы, сообщите мне об этом в комментарии, и я опубликую его.

Чтобы показать, где создается код:

public partial class Main : Form // new class for the form itself
    {
        // all of these are declared outside any method:
        TcpClient sck_client = default(TcpClient);
        Thread chatThread = default(Thread);
        string readData = null;
        StreamWriter sw = default(StreamWriter);
        StreamReader sr = default(StreamReader);
        ...

Ответы [ 2 ]

4 голосов
/ 26 сентября 2011

Хорошо, эта строка - ваша проблема:

TcpClient sck_client = default(TcpClient);

в частности:

default(TcpClient);

default() вернет значение по умолчанию для данного типа. Если тип является ссылочным типом (например, классом), он вернет null. Если тип является типом значения (например, int), он попытается установить его на 0.

Ключевое слово по умолчанию НЕ создает новый экземпляр класса для вас, вам нужно использовать ключевое слово new.

Я бы серьезно прочитал это: http://msdn.microsoft.com/en-us/library/fa0ab757.aspx

3 голосов
/ 26 сентября 2011
TcpClient sck_client = default(TcpClient);
...
sck_client.Connect("127.0.0.1", 8888);

в какой-то момент вам нужно будет дать ему значение, отличное от null (default для TcpClient равно null). Кроме того, вам, вероятно, не нужен StreamWriter только для отправки string - я бы посмотрел на использование Encoding (для получения байтов; обычно UTF8) и префикса длины размера (в байтах) ).

...