3

I'm starting development on a new Application, and although my background is mainly Mac/iOS based, I need to work on a Windows application for participation in their Imagine cup.

This project includes communication between clients through a socket connection (to a server, not ad-hoc), and I need for both Mac and Windows clients to be able to communicate with each other. I'd also like to not have to write this networking code twice, and simply write different native-UI code on both platforms. This makes the networking easier (I'm confident that two different platforms are not going to be interacting with the server in different ways) and allows for a native UI on both platforms.

Is C++ the best language for this task? Is the standard library the same on both platforms? I understand that I'll have to use Microsoft's Visual C++ library, as it seems as though it is hard to utilize C++ code from C#; is this true?

I've never really written a cross-platform application before, especially one that deals with networking between platforms.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Matt Egan
  • 809
  • 1
  • 10
  • 16

5 Answers5

5

If you're going to use C++, I second "the_mandrill" above by strongly recommending you look at ASIO in Boost - that is a great way to write the code once and support both platforms.

As to whether or not C++ is the right language is rather more subjective. My personal feelings are that if you need to ask, odds on, it's not the best approach.

Reasons for selecting C++ to implement networking code are:

  • Possible to achieve very low latencies and high throughput with very carefully designed and implemented code.
  • Possible to take explicit control of memory management - avoiding variations in performance associated with garbage collection.
  • Potential for tight integration of networking code in-process with other native libraries.
  • Potential to build small components suitable for deployment in resource constrained environments.
  • Low level access to C socket API exposes features such as socket options to use protocols beyond vanilla TCP/IP and UDP.

Reasons for avoiding C++ are:

  • Lower productivity in developing code compared with higher-level languages (e.g. Java/C#/Python etc. etc.)
  • Greater potential for significant implementation errors (pointer-abuse etc.)
  • Additional effort required to verify code compiles on each platform.

Alternatives you might consider include:

  • Python... directly using low level socket support or high-level Twisted library. Rapid development using convenient high-level idioms and minimal porting effort. Biggest disadvantage - poor support to exploit multiple processor cores for high-throughput systems.
  • Ruby(socket)/Perl(IO::Socket)... High level languages which might be particularly suited if the communicated information is represented as text strings.
  • Java... garbage collection simplifies memory management; wide range of existing libraries.
  • CLR languages (C# etc.) also garbage collected - like Java... WCF is an effective framework within which bespoke protocols can be developed... which may prove useful.

You also asked: "I understand that I'll have to use Microsoft's Visual C++ library, as it seems as though it is hard to utilize C++ code from C#; is this true?"

You can avoid Visual C++ libraries entirely - either by developing using a language other than C++, or using an alternate C++ compiler - for example Cygwin or MinGW offer G++... though I'd recommend using Visual C++ to build C and C++ code for Windows.

It's not hard to use C++ code from C# - though I don't recommend it as an approach.. it's likely overly complicated. Visual C++ can (optionally) compile "Managed Code" from C++ source (there are a few syntax extensions to grasp and there's a slightly different syntax for interoperation using Mono rather than Visual C++, but these are not major issues IMHO.) These CLR objects interact directly with C# objects and can be linked together into a single assembly without issue. It's also easy to access native DLLs (potentially written using C++ for the native architecture) using Pinvoke. All this is somewhat irrelevant, however, as the .Net framework has good support for low level networking (similar to that provided by Winsock[2]) in system.net - this provides a convenient C#-oriented interface to similar facilities, and will likely provide a more convenient API to develop against if using C# (or VB.Net or any of the other CLR languages.)

aSteve
  • 1,956
  • 1
  • 20
  • 35
  • I think the first two disadvantages you list for C++ are only relevant if the developer is not proficient with it (or in other words it assumes that they aren't). – Tamás Szelei Dec 05 '11 at 18:48
  • Productivity and potential for errors is subjective, I admit.... and familiarity with languages remains relevant. I'd argue, however, that any developer adept enough to implement good C++ can quickly become proficient developing using higher level idioms in other languages - and reap benefits from so doing. It is never a question of which language is "best" - rather a question of which tools best fit the specific requirements of each given project. – aSteve Dec 05 '11 at 20:25
  • I'm looking at C++ because it'd be relatively easy to access the code from my Objective-C and from the additional C++ code (Or... C# possibly) I'd be writing on the Windows side. -- I have done a bit of python, but it seems a bit more convoluted and complicated to get python code (which would be the networking portions of my application) to interface with Objective-C and C++, which would mean pain on both platforms. Does anything easier (For python, ruby or perl and such) exist? – Matt Egan Dec 06 '11 at 00:13
  • On the whole, I'd strongly argue against using more than one technology per process - and perhaps more than one technology per project - though a well defined protocol should minimise the overhead of using one technology for the client and another for the server. If other considerations constrain you to Objective C (while I'm not very familiar with that language) I'd suggest looking at its libraries... AsyncSocket, CFSocket and CFStream classes stand out as noteworthy. (Inter)networking support is almost ubiquitous these days - pick a language then review its available libraries. :) – aSteve Dec 06 '11 at 14:03
  • Okay. I think you're right as well. I was planning to document the protocol very, very well (As this is an application that I plan to be taking very far into the future) and I attempted writing some Objective-C++ code, and... it proved to be very strange and quirky. Also, I've done more C# than C++ and from what I've heard windows applications are significantly easier to write in C#. -- It looks like I'll document the networking code extremely well, and duplicate it on each platform. Shouldn't be too difficult. Thanks for your massive amount of help! – Matt Egan Dec 07 '11 at 04:54
3

I would suggest that you take a look at Qt. IMO Qt is one of the best C++ libraries for doing cross-platform application. The benefits of Qt when comparing with Boost is that Qt have even GUI classes.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
Lucian
  • 3,407
  • 2
  • 21
  • 18
  • 1
    Also, Qt has [QStateMachine](http://doc.qt.nokia.com/latest/qstatemachine.html) which can be used to implement a fast and solid logic for message parsing. – Tamás Szelei Dec 05 '11 at 18:50
  • Unfortunately, I have to utilize Microsoft technologies to participate in the Microsoft competition. Additionally, I have extensive knowledge with Objective-C and Cocoa, so I'd like to use that where possible. – Matt Egan Dec 06 '11 at 00:12
  • For MS technologies, I think you need to target CLR. This question's answers might help you... http://stackoverflow.com/questions/245721/what-will-it-take-to-add-objective-c-support-to-the-net-common-language-runtime – aSteve Dec 06 '11 at 14:07
1

Best language is very subjective, but if you want portable fast code with useful abstractions and C style syntax the C++ is a good choice. Note if you do not know any C++ already there is a steep learning curve.

The library as defined by the ISO standard is by definition the same on each platform, however the implementation of it my be less or more compliant. That said, both gcc, clang and MSVC(post .net) all implement C++98 very well. So long as you don't use compiler specific extensions.

I strong recommend looking at boost asio (and the boost library in general) for your networking, it uses the proactor design pattern which is very efficient. However it does take some time getting your head around it.

http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio.html

Stick with the Standard library and boost and for the most part cross platform problems are not a major concern.

Lastly, I would avoid using the C++11 features for writing cross platform code, because MSVC, GCC and Clang have all implemented different parts of the standard.

111111
  • 15,686
  • 6
  • 47
  • 62
  • Very neat, thanks! Is there anything I'm going to have to do to have the C++ compile on both platforms? Preprocessing and such? -- Also, could anyone reccomend some resources to get started with C++ (I've used it before but not extensively) and on interfacing it with objective-c code? -- You people always amaze me with how helpful you always are, thanks! – Matt Egan Dec 05 '11 at 18:08
  • Avoid C++11 features --> Use the ones the compilers you want to use/support. Clang is definite to catch up, if you really need MSVC compatibility, stick to its feature set. – rubenvb Dec 05 '11 at 18:23
  • Vanilla C++ will compile on any C++ compiler... but to get much useful work done you'll need to use APIs, and it is important when using an API to understand which platform(s) the API can work for. For example if you use the Win32 API, your code will only compile under Windows. The BSD sockets API (socket(), bind(), select(), etc) will (mostly) work under almost any OS, so you can use it for cross-platform networking. But if you are new to C++ and want an easier learning curve, I highly recommend Qt. Even if you don't need a GUI, signals-and-slots are easier to use than bare BSD sockets. – Jeremy Friesner Dec 05 '11 at 18:28
0

If you want to spend a year and put in a 1000 hrs sure use boost::asio. Or you can use a library that's built around boost::asio that invokes C++ network templates. This is crossplatform network and you can find it here: https://bitbucket.org/ptroen/crossplatformnetwork/src/master/

It compiles on Windows,Android, Macos and Linux.

That is not to say if your absolutely expert level in boost::asio you can do a tiny bit better in performance but if you want to get like 98% of the performance gains you may find it useful. It also supports HTTP,HTTPS,NACK,RTP,TCP ,UDP,MulticastServer and Multicast Client.

Examples: TCPServer: https://bitbucket.org/ptroen/crossplatformnetwork/src/master/OSI/Application/Stub/TCPServer/main.cc HTTPServer: https://bitbucket.org/ptroen/crossplatformnetwork/src/master/OSI/Application/Stub/HTTPServer/httpserver.cc

OSI::Transport::TCP::TCP_ClientTransport<SampleProtocol::IncomingPayload<OSI::Transport::Interface::IClientTransportInitializationParameters>, SampleProtocol::OutgoingPayload<OSI::Transport::Interface::IClientTransportInitializationParameters>, 
    SampleProtocol::SampleProtocolClientSession<OSI::Transport::Interface::IClientTransportInitializationParameters>, OSI::Transport::Interface::IClientTransportInitializationParameters> tcpTransport(init_parameters);;
SampleProtocol::IncomingPayload< OSI::Transport::Interface::IClientTransportInitializationParameters> request(init_parameters);
request.msg = init_parameters.initialPayload;
std::string ipMsg=init_parameters.ipAddress;
LOGIT1(ipMsg)
tcpTransport.RunClient(init_parameters.ipAddress, request);

I'm biased because I wrote the library.

ptroen
  • 21
  • 3
  • It is a good idea to add the code, instead of links because the code might change later on. Also If you really want to add some links you can add those in the context section. – Rishabh Deep Singh Mar 02 '22 at 12:03
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Mar 02 '22 at 12:03
0

You can also check for this communication library: finalmq

This library has the following properties: C++, cross-platform, async/non-blocking, multiple protocols (TCP, HTTP, mqtt5), multiple encoding formats (json, protobuf). Check the examples.

eberhard
  • 86
  • 4