tcpClient和IRC客户端问题

时间:2014-07-17 05:33:39

标签: c# tcpclient irc

有人可以告诉我为什么以下代码无效吗?

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();
    }

WORKING:

    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,而且接受的回答建议我在所有发送请求的末尾添加换行符。

2 个答案:

答案 0 :(得分:4)

您在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。

答案 1 :(得分:0)

此处需要考虑的其他问题是,大多数irc服务器会向您发送一个" ping cookie"当你连接。这包含一条带有随机字符串作为参数的PING消息。您必须使用包含相同随机字符串的PONG对此做出响应,否则您的连接将以" Ping超时"终止。信息。这是一种通过代理防止使用irc的简单方法,这种方法很常见。

您应该将功能添加到您的客户端中。