草庐IT

C# TcpClient 更新(对于 IRC 客户端)

coder 2023-09-19 原文

我基本上是在尝试使用 C#、WinForms 和 TcpClient 制作一个准系统 IRC 客户端,它将显示来自 irc 服务器的原始数据到文本区域 (textbox1)。但是我正在努力更新代码(从服务器读取流)。现在我有一个计时器,它运行一个函数 (listener),每 100 毫秒从 TCP 流中读取一次。但是,我的应用程序卡住并且光标消失,并且应用程序挂起以尝试获取更多数据。那么什么是更好的更新功能呢?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net.Sockets;

namespace LogernIRC
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //Variables
        TcpClient client;
        StreamReader sr;
        StreamWriter sw;
        //Functions
        public void connect(string host)
        {
            client = new TcpClient(host, 6667);
            sr = new StreamReader(client.GetStream());
            sw = new StreamWriter(client.GetStream());
        }
        public void write(string str)
        {
            textBox1.Text += str;
        }
        public void sendData(string str)
        {
            sw.WriteLine(str);
            sw.Flush();
        }
        public void listener()
        {
                string data = sr.ReadLine();
                write(data);
        }
        //End Functions
        private void Form1_Load(object sender, EventArgs e)
        {
            //Initialize
            write("Welcome to LogernIRC. Type \"/help\" for help with commands.\r\n");
        }

        private void button1_Click(object sender, EventArgs e) //Submit button clicked
        {
            //TextBox 1 is the text area , textbox 2 is the message/command area
            //Command Area
            if (textBox2.Text == "/help")
            {
                write("Help:\r\n/connect Connect to IRC server\r\n/help Display this help menu\r\n/join Join channel");
            }
            if (textBox2.Text.StartsWith("/connect"))
            {
                write("\r\nConnecting to " + textBox2.Text.Split(' ')[1] + " on port 6667...");
                connect(textBox2.Text.Split(' ')[1]);
            }
            if (textBox2.Text.StartsWith("/join"))
            {
                write("\r\nJoining channel " + textBox2.Text.Split(' ')[1]);
            }
            if (textBox2.Text == "/test")
            {
                timer1.Start();
                connect("irc.freenode.net");
                write("\r\nActivating test function...");
                sendData("NICK Logern");
                sendData("USER Logern 0 * :LOGERN");
                listener();
            }
        }

        private void timer1_Tick(object sender, EventArgs e) 
        {
            //Read Data
            listener();
        }
    }
}

最佳答案

延迟发生在您的计时器事件被引发但没有数据可读时。它只会坐等直到出现。解决该问题的最佳方法是使用异步操作来处理 I/O。例如:

public Form1()
{
    InitializeComponent();
}
//Variables
TcpClient client;
StreamReader sr;
StreamWriter sw;
//Functions
public void connect(string host)
{
    client = new TcpClient(host, 6667);
    sr = new StreamReader(client.GetStream());
    sw = new StreamWriter(client.GetStream());
}
public void write(string str)
{
    textBox1.Text += str;
}
public void sendData(string str)
{
    sw.WriteLine(str);
    sw.Flush();
}
public async Task listener()
{
    try
    {
        string data

        while ((data = await sr.ReadLineAsync()) != null)
        {
            write(data);
        }
    }
    catch (ObjectDisposedException)
    {
        // socket was closed forcefully
    }
}
//End Functions
private void Form1_Load(object sender, EventArgs e)
{
    //Initialize
    write("Welcome to LogernIRC. Type \"/help\" for help with commands.\r\n");
}

private void button1_Click(object sender, EventArgs e) //Submit button clicked
{
    //TextBox 1 is the text area , textbox 2 is the message/command area
    //Command Area
    if (textBox2.Text == "/help")
    {
        write("Help:\r\n/connect Connect to IRC server\r\n/help Display this help menu\r\n/join Join channel");
    }
    if (textBox2.Text.StartsWith("/connect"))
    {
        write("\r\nConnecting to " + textBox2.Text.Split(' ')[1] + " on port 6667...");
        connect(textBox2.Text.Split(' ')[1]);
    }
    if (textBox2.Text.StartsWith("/join"))
    {
        write("\r\nJoining channel " + textBox2.Text.Split(' ')[1]);
    }
    if (textBox2.Text == "/test")
    {
        connect("irc.freenode.net");

        // initiate async reading (storing the returned Task in a variable
        // prevents the compiler from complaining that we don't await the
        // call).
        var _ = listener();

        write("\r\nActivating test function...");
        sendData("NICK Logern");
        sendData("USER Logern 0 * :LOGERN");
    }
}

上面的示例省略了一些错误检查和其他细节,但这是您想要执行的操作的基本概念。

关于C# TcpClient 更新(对于 IRC 客户端),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27239370/

有关C# TcpClient 更新(对于 IRC 客户端)的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  3. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  4. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  5. ruby-on-rails - Rails Associations 的更新方法是什么? - 2

    这太简单了,太荒谬了,我在任何地方都找不到关于它的任何信息,包括API文档和Rails源代码:我有一个:belongs_to关联,我开始理解当您没有关联时您在Controller中调用的正常模型方法与您有关联时调用的方法略有不同。例如,我的关联在创建Controller操作时运行良好:@user=current_user@building=Building.new(params[:building])respond_todo|format|if@user.buildings.create(params[:building])#etcetera但我找不到关于更新如何工作的文档:@user

  6. ruby-on-rails - OSX Yosemite 更新破坏了 pow.cx - 2

    升级到OSXYosemite后,我现有的pow.cx安装不起作用。升级到最新的pow.cx无效。通过事件监视器重新启动它也没有成功。 最佳答案 卸载(!)并重新安装解决了这个问题。curlget.pow.cx/uninstall.sh|shcurlget.pow.cx|sh 关于ruby-on-rails-OSXYosemite更新破坏了pow.cx,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/q

  7. ruby - 将 Gitlab 从 9.3.7 更新到 9.3.8 安装 re2 时出错 - 2

    我们在Ubuntu14.04和Gitlab9.3.7上运行,运行良好。我们正在尝试更新到Gitlabv9.3.8的最新安全补丁,但它给我们这个错误:Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension.currentdirectory:/home/git/gitlab/vendor/bundle/ruby/2.3.0/gems/re2-1.0.0/ext/re2/usr/local/bin/ruby-r./siteconf20170720-19622-15i0edf.rbextconf.rbcheckingformain(

  8. ruby-on-rails - Rails 更新属性 - 2

    我遇到了以下问题。我有一个名为user的模型,它有一个名为activated的列。我试图通过激活的方法更新该值?但它给我错误:验证失败:密码不能为空,密码太短(最少6个字符)这对我来说没有意义,因为我没有接触密码字段!我只想更新激活的列。我把我认为相关的代码放在这里,但如果你认为你需要更多,请问:)非常感谢您!型号:attr_accessor:passwordattr_accessible:name,:email,:password,:password_confirmation,:activatedhas_many:sucu_votesemail_regex=/\A[\w+\-.]+@

  9. ruby-on-rails - 如果存在则更新,否则什么也不做? - 2

    当且仅当模型存在时,我才尝试更新模型的值。如果没有,我什么都不做。搜索似乎只返回更新或创建问题/答案,但我不想创建。我知道我可以用一个简单的方法来做到这一点:found=Model.find_by_id(id)iffoundupdatestuffend但是,我觉得有一种方法可以在一次调用中完成此操作,而无需分配任何临时本地值或执行if。如果记录不存在,我该如何编写一个Rails调用来更新记录而不出现嘈杂错误?最新的Rails3.x 最佳答案 您可以使用try在对find_by_id或where的结果调用update_attribut

  10. ruby - 在 TCPServer (Ruby) 中,我如何从客户端获取 IP/MAC? - 2

    我想在Ruby的TCPServer中获取客户端的IP地址。以及(如果可能的话)MAC地址。例如,Ruby中的时间服务器,请参阅评论。tcpserver=TCPServer.new("",80)iftcpserverputs"Listening"loopdosocket=tcpserver.acceptifsocketThread.newdoputs"Connectedfrom"+#HERE!HowcanigettheIPAddressfromtheclient?socket.write(Time.now.to_s)socket.closeendendendend非常感谢!

随机推荐