【问题标题】:tcpClient and IRC client issuestcpClient 和 IRC 客户端问题
【发布时间】:2014-08-08 16:29:49
【问题描述】:

谁能告诉我为什么下面的代码不起作用?

using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace TCPClient {
    public partial class Form1 : Form {

        private TcpClient client;
        private Thread readThread;
        private NetworkStream stream;
        private Stream dataStream;
        private Encoding dataStreamEncoding;
        private StreamWriter writer;
        private StreamReader reader;

        public Form1() {
            InitializeComponent();

            this.client = new TcpClient();
            this.readThread = new Thread(ReadLoop);
            this.dataStreamEncoding = Encoding.Default;

            Thread.CurrentThread.Name = "MainThread";
            this.readThread.Name = "ReadThread";
        }

        private void btnConnect_Click(object sender, EventArgs e) {
            if (this.client != null && !this.client.Connected) {


                try {
                    this.client.Connect("open.ircnet.net", 6666);

                    if (this.client != null && this.client.Connected) {
                        Console.WriteLine("Connected");
                    }

                    // Set up network I/O objects.
                    this.stream = this.client.GetStream();
                    this.writer = new StreamWriter(this.stream, this.dataStreamEncoding);
                    this.reader = new StreamReader(this.stream, this.dataStreamEncoding);

                    //HandleClientConnected(state.Item3);
                    this.readThread.Start();
                } catch (Exception ex) {
                    Console.WriteLine(ex.Message);
                }
            }
        }

        private void btnPing_Click(object sender, EventArgs e) {
            Console.WriteLine("Ping Sent");
            this.writer.Write("PING");
            this.writer.Flush();
        }

        private void btnLogin_Click(object sender, EventArgs e) {
            Console.WriteLine("Login Info Sent");
            this.writer.Write(  "PASS *\r\n" + 
                                "NICK testing3134\r\n" + 
                                "USER guest 8 * :\"John Doe\"");
            this.writer.Flush();
        }

        private void ReadLoop() {
            try {
                // Read each message from network stream, one per line, until client is disconnected.
                while (this.client != null && this.client.Connected) {
                    var line = this.reader.ReadLine();
                    if (line == null)
                        break;

                    Console.WriteLine(line);
                }

                if(!this.client.Connected) {
                    Console.WriteLine("Disconnected");
                }
            } catch(Exception ex) {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

控制台:

Connected
:ircnet.eversible.com 020 * :Please wait while we process your connection to ircnet.eversible.com
Login Info Sent
Ping Sent
The thread 'ReadThread' (0x10bc) has exited with code 0 (0x0).
ERROR :Closing Link: testing3134[unknown@24.255.34.216] (Ping timeout)

使其工作的更改:

原文:

    private void btnPing_Click(object sender, EventArgs e) {
        Console.WriteLine("Ping Sent");
        this.writer.Write("PING");
        this.writer.Flush();
    }

    private void btnLogin_Click(object sender, EventArgs e) {
        Console.WriteLine("Login Info Sent");
        this.writer.Write(  "PASS *\r\n" + 
                            "NICK testing3134\r\n" + 
                            "USER guest 8 * :\"John Doe\"");
        this.writer.Flush();
    }

工作:

    private void btnPing_Click(object sender, EventArgs e) {
        Console.WriteLine("Ping Sent");
        this.writer.WriteLine("PING\r\n");
        this.writer.Flush();
    }

    private void btnLogin_Click(object sender, EventArgs e) {
        Console.WriteLine("Login Info Sent");
        this.writer.WriteLine("PASS *\r\n");
        this.writer.Flush();
        this.writer.WriteLine("NICK testing3134\r\n");
        this.writer.Flush();
        this.writer.WriteLine("USER guest 8 * :\"John Doe\"\r\n");
        this.writer.Flush();
    }

我不仅从Write 切换到WriteLine,而且就像接受的答案所暗示的那样,我在所有正在发送的请求的末尾添加了换行符。

【问题讨论】:

  • 您是否打算在 IRC 命令的末尾传递一个换行符?您不会在 PING 或 USER 末尾。
  • 我不确定是否需要换行才能发送命令。我相信这只是writer.Write()
  • 我建议你确定一下。没有新行会很奇怪,否则服务器无法轻易判断您何时完成命令。

标签: c# tcpclient irc


【解决方案1】:

您没有在 PING 或 USER 消息之后包含换行符。

来自RFC 2812

IRC 消息总是以 CR-LF(回车 - 换行)对结尾的字符行

所以你应该有:

this.writer.Write("PASS *\r\n" + 
                  "NICK testing3134\r\n" + 
                  "USER guest 8 * :\"John Doe\"\r\n");

和:

this.writer.Write("PING\r\n");

如果我是你,我也会避免使用 Encoding.Default。 RFC 规定不使用特定的字符编码,但它确实希望它是 8 位的(而不是潜在的多字节)。这是指定编码的糟糕方式,但我可能会明确使用 ASCII 或 ISO-8859-1。

【讨论】:

  • 没有变化。同样的结果,没有从服务器收到任何返回消息。
  • 那时,我建议您使用 Wireshark 查看流量方面的情况 - 观察真实客户端的情况以及您的代码发生的情况。
  • 你是天啊!!!谢谢你所有的建议,特别是wireshark的东西。我想知道是不是 tcpClient 搞砸了并且没有捕获响应,但我让它工作了。我将编辑我的原始帖子以反映我所做的更改!非常感谢:)
  • @Rawr:你不应该需要 WriteLine 以及明确地放入换行符......
【解决方案2】:

这里要考虑的其他一点是,大多数 irc 服务器会在您连接时向您发送“ping cookie”。这包括一个以随机字符串作为参数的 PING 消息。您必须使用包含相同随机字符串的 PONG 对此进行响应,否则您的连接将因“Ping Timeout”消息而终止。这是一种防止通过代理即发即弃使用 irc 的简单方法,并且非常常见。

您应该在您的客户端中添加与此相关的功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 1970-01-01
    • 2012-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多