简体   繁体   English

c ++ / cli检查网络连接

[英]c++/cli Checking Network Connectivity

so here is the code 所以这是代码

public: static bool TcpSocketTest ()
    {
        try
        {
            System::Net::Sockets::TcpClient Client = gcnew System::Net::Sockets::TcpClient ("www.google.com", 80);

            Client.Close ();

            return true;
        }
        catch (System::Exception ^ex)
        {
            return false;
        }
    }

I'm trying to check the network connectivity and found this code on the internet and changed it a bit to work with my project but it says 我正在尝试检查网络连接,并在Internet上找到了此代码,并对其进行了一些更改以与我的项目一起工作,但是它说

no suitable user-defined conversion from "System::Net::Sockets::TcpClient ^" to "System::Net::Sockets::TcpClient" exists     Project1   33  

And I'm pretty much new to this so i don't know what I'm doing. 我对此很陌生,所以我不知道自己在做什么。

In C++/CLI you need to declare object references with a trailing ^ , analogous to the * operator for native pointers. 在C ++ / CLI中,您需要用尾随^声明对象引用,类似于本机指针的*运算符。 Moreover, methods on references most be invoked with the -> operator. 而且,引用上的方法大多数是通过->运算符调用的。 Try this: 尝试这个:

public: static bool TcpSocketTest ()
    {
        try
        {
            System::Net::Sockets::TcpClient^ Client = gcnew System::Net::Sockets::TcpClient ("www.google.com", 80);

            Client->Close ();

            return true;
        }
        catch (System::Exception ^ex)
        {
            return false;
        }
    }

EDIT: As Hans Passant points out correctly, there's still another problem with this code, which is not syntactical. 编辑:正如汉斯·帕桑特(Hans Passant)正确指出的那样,此代码还有另一个问题,这不是语法问题。 Since TcpClient implements IDisposable , and the Close() call is located in the try block, the object reference is never disposed of in case of an exception. 由于TcpClient实现IDisposable ,并且Close()调用位于try块中,因此在发生异常的情况下永远不会丢弃对象引用。 So the Close() call should be outside the try block. 因此, Close()调用应位于try块之外。

However, C++/CLI offers a much better way for dealing with this problem, which is called "stack semantics". 但是,C ++ / CLI提供了一种更好的方法来处理此问题,称为“堆栈语义”。 It's equivalent to the C# using statement. 等效于C# using语句。 It's used like that: 它的用法是这样的:

public: static bool TcpSocketTest ()
    {
        try
        {
            System::Net::Sockets::TcpClient Client (L"www.google.com", 80);

            // Dispose() or Close() not needed anymore

            return true;
        }
        catch (System::Exception ^ex)
        {
            return false;
        }
    }

So the TcpClient reference is declared like a local variable. 因此, TcpClient引用的声明类似于局部变量。 But actually, it will be created on the heap, and as soon as the variable Client goes out of scope, Client.Dispose () will be called automatically. 但是实际上,它将在堆上创建,并且一旦变量Client超出作用域,就会自动调用Client.Dispose () Hence the Close() call is unnecessary altogether, and the object is disposed of properly, no matter if an exception is thrown or the method terminates normally. 因此,无论是否引发异常或方法正常终止,都完全不需要Close()调用,并且可以正确处理该对象。

Thanks to Hans Passant for pointing this out. 感谢Hans Passant指出这一点。 Stack semantics for IDispose are good practice in C++/CLI. IDispose堆栈语义是C ++ / CLI中的良好实践。

Note that I changed the String literal in the constructor to L"..." . 请注意,我将构造函数中的String文字更改为L"..." This is good practice, too, because omitting the "L" will result in problems as soon as Unicode characters outside the 8-bit range are used. 这也是一个好习惯,因为一旦使用8位范围以外的Unicode字符,则省略“ L”将导致问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM