我试图编写一个简单的IRC机器人,但我得到null异常为什么会这样?

时间:2013-08-23 06:34:18

标签: c# winforms

这是我Form1的代码:

namespace Irc_Bot
{
    public partial class Form1 : Form
    {
        int port;
        string buf, nick, owner, server, chan;
        System.Net.Sockets.TcpClient sock = new System.Net.Sockets.TcpClient();
        System.IO.TextReader input;
        System.IO.TextWriter output;

        public Form1()
        {
            InitializeComponent();

            //Get nick, owner, server, port, and channel from user
            label1.Text = "Enter bot nick: ";
            nick = textBox1.Text;
            label2.Text = "Enter bot owner name: ";
            owner = textBox2.Text;
            label3.Text = "Enter server name: ";
            label4.Text = "Enter port number: ";
            if (textBox4.Text != "")
            port = Convert.ToInt32(textBox4.Text);
            label5.Text = "Channel: ";
            chan = textBox5.Text;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }

        private void connectToIrc()
        {
            //Connect to irc server and get input and output text streams from TcpClient.
            server = textBox3.Text;
            port = Convert.ToInt32(textBox4.Text);
            sock.Connect("chat.eu.freenode.net", port);//server, port);

            if (!sock.Connected)
            {
                Console.WriteLine("Failed to connect!");
                return;
            }

            input = new System.IO.StreamReader(sock.GetStream());
            output = new System.IO.StreamWriter(sock.GetStream());

             //Starting USER and NICK login commands 
         output.Write(
            "USER " + nick + " 0 * :" + owner + "\r\n" +
            "NICK " + nick + "\r\n"
         );

         output.Flush();

         //Process each line received from irc server
         for (buf = input.ReadLine(); ; buf = input.ReadLine())
         {
             //Display received irc message
             Console.WriteLine(buf);

             //Send pong reply to any ping messages
             if (buf.StartsWith("PING ")) { output.Write(buf.Replace("PING", "PONG") + "\r\n"); output.Flush(); }
             if (buf[0] != ':') continue;

             /* IRC commands come in one of these formats:
              * :NICK!USER@HOST COMMAND ARGS ... :DATA\r\n
              * :SERVER COMAND ARGS ... :DATA\r\n
              */

             //After server sends 001 command, we can set mode to bot and join a channel
             if (buf.Split(' ')[1] == "001")
             {
                 output.Write(
                    "MODE " + nick + " +B\r\n" +
                    "JOIN " + chan + "\r\n"
                 );
                 output.Flush();
             }
         }
       }

        private void button1_Click(object sender, EventArgs e)
        {
            connectToIrc();
        }
    }
}

例如,我输入chat.eu.freenode.net作为服务器名称,输入6667作为端口。

如果我通过MIRC程序进入此服务器,它就能正常工作。

但是在FOR循环中经过3-4次迭代后我的程序中,我在这一行得到异常null:

if (buf.StartsWith("PING "))

变量bufnull

首先,它执行迭代一段时间,然后执行命令的次数为3-5次continue;,然后挂起将近15秒然后跳转到该行:

if (buf.StartsWith("PING ")) 

并抛出异常空消息。

  

对象引用未设置为对象的实例

     

System.NullReferenceException未处理
  的HResult = -2147467261
  Message =对象引用未设置为对象的实例   来源= Irc Bot

如何解决?

1 个答案:

答案 0 :(得分:5)

这部分代码可能是造成错误的原因。

for (buf = input.ReadLine(); ; buf = input.ReadLine())

如果只发送一行,则第一个ReadLine占用该行,第二个读取为空,如果只发送一行,则导致buf为空。

删除其中一个buf = input.ReadLine(),并在开始处理之前添加buf != null的检查。这可能看起来像这样。请注意,在while循环之前和结束时都有buf = input.ReadLine();。我还在中间添加了一个ERROR检查,因为我在使用一些无效参数进行测试时在if (buf[0] != ':') continue;上遇到了无限循环。

//Process each line received from irc server
buf = input.ReadLine();
while (buf != null)
{

  //Display received irc message
  Console.WriteLine(buf);

  if (buf.StartsWith("ERROR")) break;

  //Send pong reply to any ping messages
  if (buf.StartsWith("PING ")) { output.Write(buf.Replace("PING", "PONG") + "\r\n"); output.Flush(); }
  if (buf[0] != ':') continue;

  //After server sends 001 command, we can set mode to bot and join a channel
  if (buf.Split(' ')[1] == "001")
  {
    output.Write(
      "MODE " + nick + " +B\r\n" +
      "JOIN " + chan + "\r\n"
    );
    output.Flush();
  }
  buf = input.ReadLine();
}