Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 无法在Socket.BeginConnect()的回调函数中使用断点_C#_Sockets - Fatal编程技术网

C# 无法在Socket.BeginConnect()的回调函数中使用断点

C# 无法在Socket.BeginConnect()的回调函数中使用断点,c#,sockets,C#,Sockets,这里有两个函数。当我打电话时 public bool Connect (string address, int remotePort) { if (_socket != null && _socket.Connected) return true; IPHostEntry hostEntry = Dns.GetHostEntry (address); foreach (IPAddress

这里有两个函数。当我打电话时

    public bool Connect (string address, int remotePort)
    {
        if (_socket != null && _socket.Connected)
            return true;


        IPHostEntry hostEntry = Dns.GetHostEntry (address);
        foreach (IPAddress ip in hostEntry.AddressList) {
            try {
                IPEndPoint ipe = new IPEndPoint (ip, remotePort);

                _socket = new Socket (ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                _socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);

                break;

            } catch (System.Exception e) {
                PushPacket ((ushort)MsgIds.Id.CONNECTION_ATTEMPT_FAILED, e.Message);
                return false;
            }

        }

        return true;
    }

    void ConnectionCallback (System.IAsyncResult ar)
    {
        NetBitStream stream = new NetBitStream ();

        stream._socket = (Socket)ar.AsyncState;

        try {
            _socket.EndConnect (ar);

            _socket.SendTimeout = _sendTimeout;
            _socket.ReceiveTimeout = _revTimeout;

            PushPacket ((ushort)MsgIds.Id.CONNECTION_REQUEST_ACCEPTED, "");

            _socket.BeginReceive (stream.BYTES, 0, NetBitStream.HEADER_LENGTH, SocketFlags.None, new System.AsyncCallback (ReceiveHeader), stream);


        } catch (System.Exception e) {
            if (e.GetType () == typeof(SocketException)) {
                if (((SocketException)e).SocketErrorCode == SocketError.ConnectionRefused) {
                    PushPacket ((ushort)MsgIds.Id.CONNECTION_ATTEMPT_FAILED, e.Message);
                } else
                    PushPacket ((ushort)MsgIds.Id.CONNECTION_LOST, e.Message);
            }

            Disconnect (0);
        }
    }
它只是跨过了休息;之后

并返回true;。我在ConnectionCallback上设置了一个断点,但它没有进入这个函数

10001端口上没有正在侦听的服务器

所以我认为它至少应该抛出一个异常connect failed,然后进入catch

还是我在这两个函数中犯了错误

下面是一个最小、完整且可验证的示例

  _socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);

我想你可能误解了BeginConnect的功能。这不会建立连接-它只是开始异步建立连接。所以,是的,我一点也不奇怪,一步一步地走到下一个语句——这是按预期进行的

然而,我本以为ConnectionCallback中的断点会被击中——这是您应该作为一个问题来关注的。这也是您应该放置异常处理的地方,因为这是创建连接时发现任何问题的地方

或者,如果您使用的是C5或更高版本,您应该考虑使用async/await,这将允许您摆脱所有回调。然后,在调试时,您将获得一种更加熟悉的体验——如果您跨过这一行,它将真正连接起来,或者在您点击下一行时出现故障。请注意,在等待响应时,即使在同一线程上也可能发生其他事情

不幸的是,我在Socket中看不到实现相关模式的任何东西。您可以使用TaskFactory.FromAsync将旧样式调整为新样式,但这可能相当痛苦


另一种方法是尝试转移到更高级别的构造,如TcpClient,而不是较低级别的Socket类。

我认为您可能误解了BeginConnect的功能。这不会建立连接-它只是开始异步建立连接。所以,是的,我一点也不奇怪,一步一步地走到下一个语句——这是按预期进行的

然而,我本以为ConnectionCallback中的断点会被击中——这是您应该作为一个问题来关注的。这也是您应该放置异常处理的地方,因为这是创建连接时发现任何问题的地方

或者,如果您使用的是C5或更高版本,您应该考虑使用async/await,这将允许您摆脱所有回调。然后,在调试时,您将获得一种更加熟悉的体验——如果您跨过这一行,它将真正连接起来,或者在您点击下一行时出现故障。请注意,在等待响应时,即使在同一线程上也可能发生其他事情

不幸的是,我在Socket中看不到实现相关模式的任何东西。您可以使用TaskFactory.FromAsync将旧样式调整为新样式,但这可能相当痛苦


另一种方法是尝试转移到更高级别的构造,如TcpClient,而不是较低级别的Socket类。

调试器不是这样工作的。除了极少数例外,如果没有您的明确指示,它将不会切换线程

当您单步执行编写的Connect方法时,您正在调试程序中的特定线程。ConnectionCallback方法在调用时(注意在调用BeginConnect期间通常不会同步调用),将在不同的线程中调用。如果要调试它,则需要在ConnectionCallback方法本身处或其中设置断点

通过在该方法中设置断点,可以确保调试器将暂停程序在那里的执行,而不管哪个线程正在执行该方法

编辑:

感谢您提供完整的代码示例。假设这实际上是您正在测试的代码示例,并且遇到了问题,那么您的问题就像我们已经猜到的两件事之一:

单步执行对Connect方法的调用后,不会恢复程序的执行。即,您没有单击“继续”按钮或使用“调试”菜单中的“继续”菜单项。或者… 您必须恢复程序的执行,然后在解决连接尝试之前立即退出。 在上面的案例1中,您永远看不到断点,因为您的程序没有执行。只有当程序的执行确实到达断点时,才能触发断点。但是如果你的程序根本没有运行,那么它的执行就无法到达那里

在上面的案例2中,您永远看不到断点,因为您的程序没有执行。在这种情况下,这是因为程序已完全退出

如果您想看到ConnectionCallback方法中的断点被触发,您需要让程序运行,并且运行的时间足够长 佩恩

作为概念的快速证明,我在该方法上设置了一个断点,并将此语句添加到主方法的末尾:

然后,我使用调试器逐步完成Main方法。它当然会暂停,让程序在我刚才添加的上述语句处运行,但随后很快又在所需的断点处中断了程序。我不必在任何地方等待近5分钟……我只是将其作为一个非常大的时间值,我确信这已经足够了


值得一提的是,我还尝试了一个测试,在该测试中,我跨过了最初的Main,即没有调用Thread.Sleep,但在跨过调用连接后等待了大约5-10秒,然后继续。在这种情况下,至少在我的计算机上,我也看到断点被触发。这个特定的测试在某种程度上取决于机器配置,因此它不如向Thread.Sleep添加调用可靠。但在我的例子中,它确实起了作用。

调试器不是这样工作的。除了极少数例外,如果没有您的明确指示,它将不会切换线程

当您单步执行编写的Connect方法时,您正在调试程序中的特定线程。ConnectionCallback方法在调用时(注意在调用BeginConnect期间通常不会同步调用),将在不同的线程中调用。如果要调试它,则需要在ConnectionCallback方法本身处或其中设置断点

通过在该方法中设置断点,可以确保调试器将暂停程序在那里的执行,而不管哪个线程正在执行该方法

编辑:

感谢您提供完整的代码示例。假设这实际上是您正在测试的代码示例,并且遇到了问题,那么您的问题就像我们已经猜到的两件事之一:

单步执行对Connect方法的调用后,不会恢复程序的执行。即,您没有单击“继续”按钮或使用“调试”菜单中的“继续”菜单项。或者… 您必须恢复程序的执行,然后在解决连接尝试之前立即退出。 在上面的案例1中,您永远看不到断点,因为您的程序没有执行。只有当程序的执行确实到达断点时,才能触发断点。但是如果你的程序根本没有运行,那么它的执行就无法到达那里

在上面的案例2中,您永远看不到断点,因为您的程序没有执行。在这种情况下,这是因为程序已完全退出

如果您想看到ConnectionCallback方法的断点被触发,您需要让程序运行,并且运行的时间足够长

作为概念的快速证明,我在该方法上设置了一个断点,并将此语句添加到主方法的末尾:

然后,我使用调试器逐步完成Main方法。它当然会暂停,让程序在我刚才添加的上述语句处运行,但随后很快又在所需的断点处中断了程序。我不必在任何地方等待近5分钟……我只是将其作为一个非常大的时间值,我确信这已经足够了


值得一提的是,我还尝试了一个测试,在该测试中,我跨过了最初的Main,即没有调用Thread.Sleep,但在跨过调用连接后等待了大约5-10秒,然后继续。在这种情况下,至少在我的计算机上,我也看到断点被触发。这个特定的测试在某种程度上取决于机器配置,因此它不如向Thread.Sleep添加调用可靠。但在我的情况下,它确实起了作用。

@PeterDuniho:有TaskFactory.fromsync,它可以为您做很多事情,但我认为最好尽可能直接使用专为异步/等待而设计的方法。是的,oops,没有发现ConnectAsync无法工作-将删除该位nothing@mingchaoyan:如果您可以发布一个简短但完整的程序来显示这一点,我们可以尝试重现该问题。我们不知道您的程序的其余部分在做什么-它可能在连接尝试成功或失败之前完成,例如…@mingchaoyan:您的主方法将完成,在异步连接有时间完成之前终止程序。例如,在Main方法的末尾添加对Console.ReadLine的调用,您将看到回调被调用。@PeterDuniho:有TaskFactory.fromsync,它可以为您做很多事情,但我认为最好尽可能直接使用专为异步/等待方法设计的方法。是的,oops,没有发现ConnectAsync无法工作-将删除该位nothing@mingchaoyan:如果您可以发布一个简短但完整的程序
这样,我们可以尝试重现这个问题。我们不知道您的程序的其余部分在做什么-它可能在连接尝试成功或失败之前完成,例如…@mingchaoyan:您的主方法将完成,在异步连接有时间完成之前终止程序。例如,在Main方法的末尾添加一个对Console.ReadLine的调用,您将看到回调被调用。事实上,我设置了一个断点,连接回调,结果什么都没有发生好,最终应该会发生一些事情。根据网络状态和超时配置,在尝试连接到不存在的端点时实际发生错误之前,可能需要一些时间。在放弃之前你等了多久?在你等待的时候你的程序在做什么?我希望调试器中还没有停止。如果您不让程序继续运行,显然无法命中断点。请留下您的电子邮件,我将向您发送全部源代码。抱歉,这不是工作方式。如果您希望有人尝试重现问题,您应该包括可靠地证明问题的内容。就个人而言,我打赌你只是误用了调试器;多年来,我调试了大量的代码,包括网络代码,如果您正确使用调试器,并且当然假设在连接尝试最终失败时程序仍在运行,那么您所描述的不应该发生。事实上,我设置了一个断点连接回调,但没有发生任何事情,总有一天会发生的。根据网络状态和超时配置,在尝试连接到不存在的端点时实际发生错误之前,可能需要一些时间。在放弃之前你等了多久?在你等待的时候你的程序在做什么?我希望调试器中还没有停止。如果您不让程序继续运行,显然无法命中断点。请留下您的电子邮件,我将向您发送全部源代码。抱歉,这不是工作方式。如果您希望有人尝试重现问题,您应该包括可靠地证明问题的内容。就个人而言,我打赌你只是误用了调试器;多年来,我调试了相当多的代码,包括网络代码,如果正确使用调试器,并且假设在连接尝试最终失败时程序仍在运行,那么您所描述的就不会发生。
  _socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);
    using System;
using System.Net.Sockets;
using System.Net;

namespace TestSocket
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            NetTCPClient tcp_client = new NetTCPClient ();
            tcp_client.Connect ("127.0.0.1", 10001);
        }
    }

    class NetTCPClient
    {
        Socket _socket = null;
        public bool Connect (string address, int remote_port)
        {
            if (_socket != null && _socket.Connected)
                return true;
            IPHostEntry host_entry = Dns.GetHostEntry (address);
            foreach (IPAddress ip in host_entry.AddressList) {
                try {
                    IPEndPoint ipe = new IPEndPoint (ip, remote_port);
                    _socket = new Socket (ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                    IAsyncResult ia = _socket.BeginConnect (ipe, new System.AsyncCallback (ConnectionCallback), _socket);
                    break;
                } catch (Exception e) {
                    Console.WriteLine ("Connet() catch an exception!");
                    return false;
                }
            }
            return true;
        }

        void ConnectionCallback (System.IAsyncResult ar)
        {
            Console.WriteLine ("ConnectionCallback() ");
        }

    }

}
Thread.Sleep(TimeSpan.FromMinutes(5));