.NET IRC TCPClient 读取挂起 30-40 分钟后

Posted

技术标签:

【中文标题】.NET IRC TCPClient 读取挂起 30-40 分钟后【英文标题】:.NET IRC TCPClient read hang after 30-40 minutes 【发布时间】:2014-02-24 16:15:24 【问题描述】:

我一直在尝试使用 TCPClient 在 C# 中编写 IRC 机器人。它连接并开始接收命令,用 PONG 命令响应 PING 命令。就是这样。

但是,由于某种原因,读取下一行数据的函数会在 30 到 40 分钟后挂起。我已经使用 Wireshark 检查了 PING 和 PONG 消息,它们对我来说看起来不错。服务器也收到了 PONG,因为我确实在 Wireshark 中看到我的计算机收到了一个 ACK​​ 数据包。

奇怪的是,它在这 30 到 40 分钟内工作得非常好。 我怀疑我在 StreamReader 上做错了,但在网上搜索了几天后,我被卡住了。

有人愿意看我的代码吗?提前非常感谢。

public class Bot

    private NetworkStream ns;
    private StreamReader reader;
    private StreamWriter writer;
    private Encoding enc;           // The encoding used.

    /// <summary>
    /// Initialize the bot.
    /// </summary>
    public Bot()
    
        enc = new UTF8Encoding();
    

    /// <summary>
    /// Connects the an IRC server.
    /// </summary>
    /// <param name="url">The url of the server.</param>
    /// <param name="port">The port to connect to.</param>
    /// <param name="user">The username to use.</param>
    /// <param name="nick">The nick to use.</param>
    /// <param name="realName">The users real name.</param>
    public void Connect(string url, ushort port, string user, string nick, string realName)
    
        TcpClient client = new TcpClient();

        try
        
            client.Connect(url, port);
        
        catch (Exception ex)
        
            throw new Exception("Could not connect to endpoint.", ex);
        

        ns = client.GetStream();
        reader = new StreamReader(ns, enc);
        writer = new StreamWriter(ns, enc);
        writer.AutoFlush = true;

        Send("USER " + user + " 0 * :" + realName + "\r\n");
        Send("NICK " + nick + "\r\n");
    

    /// <summary>
    /// Processes a command.
    /// </summary>
    /// <param name="command">The command to process.</param>
    public virtual void ProcessCommand(IRCCommand command)
    
        if(command.Command == "PING")
        
            Send("PONG :" + command.Parameters[0] + "\r\n");
        
    

    /// <summary>
    /// Receives and processes a command.
    /// </summary>
    public void ReceiveAndProcess()
    
        string line = reader.ReadLine();

        if (!string.IsNullOrEmpty(line))
        
            Console.WriteLine("raw : " + line);

            IRCCommand cmd = new IRCCommand();
            cmd.Parse(line);

            ProcessCommand(cmd);
        
    

    /// <summary>
    /// Sends a command to the irc server.
    /// </summary>
    /// <param name="ircCommand">The command to send.</param>
    protected void Send(string ircCommand)
    
        Console.Write("sent: " + ircCommand);
        writer.Write(ircCommand);
    

【问题讨论】:

【参考方案1】:

我发现问题不在 TCPClient 的实际读取中。问题是我的 ISP 在频道不活动 30 分钟后关闭了连接。由于 IRC 乒乓球是从互联网到(机器人)用户的持续请求-回复。我的 ISP 可能将这种请求-回复活动视为潜在的僵尸网络并关闭了连接。

为了防止这种情况,我将我的机器人更改为每分钟向服务器发送 PING。随着这一变化的到位,该机器人已经稳定了整整一周 (24/7)。

【讨论】:

以上是关于.NET IRC TCPClient 读取挂起 30-40 分钟后的主要内容,如果未能解决你的问题,请参考以下文章

循环直到 TcpClient 响应完全读取 [重复]

如何使用 Bash 编写的 IRC 机器人从 IRC 频道读取消息?

TCP客户端TcpClient

.net 2.0 IRC 组件

基于 .NET 的 IRC 服务器

Python字符串split()方法读取IRC时导致索引错误