【问题标题】:async TcpClient.Connect() how to use it?async TcpClient.Connect() 怎么用呢?
【发布时间】:2014-02-03 20:57:43
【问题描述】:

目前我正在将我的客户端同步连接到服务器。
但是,服务器有时不可用,所以我认为使用异步会更好,这样我就可以收集并格式化稍后要发送的数据。我发现我要找的方法大概是TcpClient.BeginConnect
不幸的是,我对异步操作完全陌生,所以参数让我很奇怪。
一方面:是否有特定原因我必须单独使用 IP 和端口,即不使用 IPEndPoint?
然而更重要的问题:AsyncCallback 和 Object,它们是什么?
我需要更改服务器上的任何内容吗?
我想我明白 snyc 或 asnyc 是本地选择,不会影响对方,至少不会影响兼容性。
最后:Here 我读到了关键字 asnyc 和 await:在哪里使用它们以及如何使用它们?

这里有一个小伪代码来演示我拥有什么以及我想要什么

private static void send(string msg) {
    TcpClient cli = new TcpClient(localEP);
    bool loop = true;
    while(loop) {      //trying over and over till it works
        try {          //is bad practice and inefficient
            cli.Connect(remoteEP);
        } catch (Exception) {
            ;
        }
        if(cli.Connected)
            break;
    }
    var blah = doOtherThings(msg);
    useTheClient(blah);
}

现在我希望它如何工作

private static void send(string msg) {
    TcpClient cli = new TcpClient(localEP);
    cli.BeginConnect(remoteEP); //thread doesn't block here anymore + no exceptions
    var blah = doOtherThings(msg); //this now gets done while cli is connecting
    await(cli.connect == done) //point to wait for connection to be established
    useTheClient(blah);
}

【问题讨论】:

    标签: c# asynchronous tcp tcpclient


    【解决方案1】:

    您需要创建一个新的AsyncCallback 并将其设置为特定的空白,一旦TcpClient 完成与主机的连接,就会在该空白处执行某些操作。您可能还想通过检查TcpClient.Connected 的值来检查TcpClient 连接是否成功

    示例

    以下示例说明了在端口 80 上与 google.com 的异步 TcpClient 连接

    static TcpClient cli = new TcpClient(); //Initialize a new TcpClient
    static void Main(string[] args)
    {
        send("Something");
        Console.ReadLine();
    }
    private static void doSomething(IAsyncResult result)
    {
        if (cli.Connected) //Connected to host, do something
        {
            Console.WriteLine("Connected"); //Write 'Connected'
        }
        else
        {
            //Not connected, do something
        }
        Console.ReadLine(); //Wait for user input
    }
    private static void send(string msg)
    {
        AsyncCallback callBack = new AsyncCallback(doSomething); //Set the callback to the doSomething void
        cli.BeginConnect("google.com", 80, callBack, cli); //Try to connect to Google on port 80
    }
    

    这是执行您在评论中描述的更好的方法

    System.Threading.Thread newThread = new System.Threading.Thread((System.Threading.ThreadStart)delegate {
    //Do whatever you want in a new thread
        while (!cli.Connected)
        {
            //Do something
        }
    });
    newThread.Start(); //Start executing the code inside the thread
    //This code will still run while the newThread is running
    Console.ReadLine(); //Wait for user input
    newThread.Abort(); //Stop the thread when the user inserts any thing
    

    【讨论】:

    • 好的,这看起来已经比我以前发现的任何东西都简单了。这意味着:“连接后,调用callback 并传递"connected"”,直到那时代码被进一步执行。到目前为止我是对的吗?除了只有 void 类型之外,回调函数的设计是否有任何限制,比如只有一个参数是 IAsyncResult?现在我该如何定义我不想在 asnyc 事件通过之前通过的点,即它必须连接的点,我不能再做任何其他事情了?
    • @Mark 是的,当您的应用程序正常运行时,代码将在后台执行。然后当 TcpClient 完成连接或尝试连接时,它将运行回调 void。回调 void 然后通过检查 cli.Connected 值来检查 TcpClient 是否成功连接,抱歉,我没有真正理解你的最后一个问题,你的意思是什么?
    • @Mark 很好,你可以使用System.Threading.Thread 来启动一个新线程,并在不干扰主线程的情况下做任何你想做的事情。我已根据您的需要编辑了帖子。
    • 最后一件事:当您调用 beginconnect 时,您传递了字符串“connected”:那个去哪儿了?
    • @Mark 那是在这篇文章的上一个版本中,我发现检查TcpClient.Connected 是一个更好的选择,所以我编辑了这篇文章。如果您想看一下,这是第一个版本的链接:stackoverflow.com/revisions/21136892/1
    猜你喜欢
    • 2015-04-07
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多