2015-07-29 3 views
0

Я использовал этот код раньше, и он сработал. Теперь, каждый раз, когда он пытается подключиться к серверу IRC, я получаю сообщение об ошибке: «Не удается прочитать из закрытого чтения текста»Ошибка C# IRC Bot: «Не удается прочитать из закрытого текстового считывателя»

Я изменил АДРЕСА на частную жизнь

Это мой код:

using System; 
using System.Net; 
using System.Net.Sockets; 
using System.IO; 
using System.Threading; 

namespace IRCBot 
{ 
class Program 
{ 

} 
class IrcBot 
{ 
    // Irc server to connect 
    public static string SERVER = "irc.rizon.net"; 
    // Irc server's port (6667 is default port) 
    private static int PORT = 6660; 
    // User information defined in RFC 2812 (Internet Relay Chat: Client Protocol) is sent to irc server 
    private static string USER = "irc_bot"; 
    // Bot's nickname 
    private static string NICK = "BotNick"; 
    // Channel to join 
    private static string CHANNEL = "#testing"; 
    // StreamWriter is declared here so that PingSender can access it 
    public static StreamWriter writer; 
    static void Main(string[] args) 
    { 
     NetworkStream stream; 
     TcpClient irc; 
     string inputLine; 
     StreamReader reader; 
     string nickname; 
     try 
     { 
      irc = new TcpClient(SERVER, PORT); 
      stream = irc.GetStream(); 
      reader = new StreamReader(stream); 
      writer = new StreamWriter(stream); 
      // Start PingSender thread 
      PingSender ping = new PingSender(); 
      ping.Start(); 
      writer.WriteLine(USER); 
      writer.Flush(); 
      writer.WriteLine("NICK " + NICK); 
      writer.Flush(); 
      writer.WriteLine("JOIN " + CHANNEL); 
      writer.Flush(); 
      while (true) 
      { 
       while ((inputLine = reader.ReadLine()) != null) 
       { 
        if (inputLine.EndsWith("JOIN :" + CHANNEL)) 
        { 
         // Parse nickname of person who joined the channel 
         nickname = inputLine.Substring(1, inputLine.IndexOf("!") - 1); 
         // Welcome the nickname to channel by sending a notice 
         writer.WriteLine("NOTICE " + nickname + " :Hi " + nickname + 
         " and welcome to " + CHANNEL + " channel!"); 
         writer.Flush(); 
         // Sleep to prevent excess flood 
         Thread.Sleep(2000); 
        } 
       } 
       // Close all streams 
       writer.Close(); 
       reader.Close(); 
       irc.Close(); 
      } 
     } 
     catch (Exception e) 
     { 
      // Show the exception, sleep for a while and try to establish a new connection to irc server 
      Console.WriteLine(e.ToString()); 
      Thread.Sleep(5000); 
      string[] argv = { }; 
      Main(argv); 
     } 
    } 
} 

class PingSender 
{ 
    static string PING = "PING :"; 
    private Thread pingSender; 
    // Empty constructor makes instance of Thread 
    public PingSender() 
    { 
     pingSender = new Thread(new ThreadStart(this.Run)); 
    } 
    // Starts the thread 
    public void Start() 
    { 
     pingSender.Start(); 
    } 
    // Send PING to irc server every 15 seconds 
    public void Run() 
    { 
     while (true) 
     { 
      IrcBot.writer.WriteLine(PING + IrcBot.SERVER); 
      IrcBot.writer.Flush(); 
      Thread.Sleep(15000); 
     } 
    } 
} 

}

+0

В какой строке ошибка? – Krishna

+0

Ошибка указана в строке 51. – Jack

+0

'IrcBot.writer' в' PingSender' также может быть закрыт или даже работает дважды. Кроме того, «По умолчанию StreamWriter не является потокобезопасным». – Caramiriel

ответ

1

Закрыть все потоки должны быть снаружи, пока:

while (true) 
      { 
       while ((inputLine = reader.ReadLine()) != null) 
       { 
        .... 
       }    
      } 
    // Close all streams 
       writer.Close(); 
       reader.Close(); 
       irc.Close(); 
+0

Это дает ошибку «недоступный код». – Jack

+0

while (true) не является хорошей практикой .. это вызывает проблему .. – apomene

0

Переместить все ваши закрытия потока линии, чтобы "наконец" блок:

try 
{ 
... 
} 
catch (Exception e) 
{ 
    Console.WriteLine(e.ToString()); 
    Thread.Sleep(5000); 
    string[] argv = { }; 
    Main(argv); 
} 
finally 
{ 
    //Close all streams 
    writer?.Close(); 
    reader?.Close(); 
    irc?.Close(); 
} 

Обратите внимание, я использовал новый C# 6 оператора нуль-распространения?. здесь ваши потоки могут быть нулевыми. Если вы используете C# ver < 6, напишите следующим образом: if (writer!=null) writer.Close();