简体   繁体   中英

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

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. 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. 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. So the Close() call should be outside the try block.

However, C++/CLI offers a much better way for dealing with this problem, which is called "stack semantics". It's equivalent to the C# using statement. 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. 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. 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.

Thanks to Hans Passant for pointing this out. Stack semantics for IDispose are good practice in C++/CLI.

Note that I changed the String literal in the constructor to 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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