I just have a simple question. I am a student and I am learning. I am not very proficient at C++, but I finally set up a working http reqest app in c++ using winsock and I just wanted to know that after compiling will the http request still be sent from other OSes that don't have WinSock?
WinSock, or at least the parts you probably will have been using for introductory networking stuff, is based off of, and largely compatible with, the BSD socket API, which is available on all current operating systems. If you don't have experience with cross-platform development it's unlikely that your code would compile the first time through on a Linux system, but the underlying techniques would be the same.
For cross-platform networking, you might want to consider something like Qt, which provides an API which will work mostly the same on all OSes without much per-platform stuff. Its networking API is also based off Berkeley sockets.
In general, though, there's just no way of checking that your code works cross-platform without testing it cross-platform. Grab a Linux distribution and try it out; note that some are specifically intended to work from your Windows disk without the need to repartition.
If you use standardized BSD-based socket functions, then your code will typically work on multiple platforms socket(), bind(), connect(), send(), recv(), etc. Caveats include:
error codes. When a WinSock/BSD function fails on Windows, the error code is retreived using WSAGetLastError(), whereas other platforms use errno instead. So you will have to wrap that portion if you are trying to write cross-platform code.
get/setsockopt() may implement different options on different platforms, not all options are standardized across all platforms.
If you use WinSock-specific functions, then your code will only work on Windows. WSASocket(), WSAConnect/Ex(), WSASend/Ex(), WSARecv/Ex(), etc.
All versions of Windows have WinSock. Most platforms, including Windows, support a BSD-based socket API.
After you compile your code, it will only run on the specific platform it was compiled for. You would have to compile the code separately for each platform you want to support.
Related
I have a Linux C++ application which run as a daemon. When user executes this application, it will be running in the background, listening on a port, and waiting for connection from the clients.
Is it possible to port this kind of application to Windows platform using Cygwin or MinGW?
Thanks.
Cygwin aims at POSIX/Linux source level compatibility, so your application is supposed to build and work there with no or only minor modifications.
MinGW does not try to provide such a compatibility layer. It's just the GNU toolchain for Windows, so you would need to replace any uses of POSIX/Linux-specific APIs with Windows equivalents.
It is possible to port almost anything (unless it makes sense only to one OS). The question is, "how hard is it to port application X"? And to help answer that question, we need to see source code.
General purpose tips
It basically boils down to how much compiler/system-dependent code you've spread out over your code base. I see you're using at least two things that are sensitive: daemons and sockets.
Daemons are tricky to port as the equivalent on Windows (a windows service) requires different platform-specific code. This is fixed cost (e.g. does not vary on the size of the rest of the application).
Sockets are more or less tricky to port depending on whether you're using advanced networking features (asynchronous I/O, etc.), which tend to vary more from system to system. It also depends on whether you abstracted socket manipulation code into some re-usable component. Windows supports a very similar sockets interface (the classic BSD socket interface with minor modifications to random parts of the API). Changing one Socket class is easier than changing your code if you didn't write a wrapper class.
I'm thinking of purchasing this book to learn more on C/C++ networking programming:
I was just wondering is there/do I need a windows equivalent book (I do plan to code on both OS'). I'm not sure of the difference in the evolution regarding BSD sockets the windows.
I'm mainly buying this to eventually write code which will stream data between computers.
"Porting Socket Applications to Winsock"
Having done both, I'd definitely start out with the BSD version. Not only will you be learning something useful on both platforms (and others), but you'll have a better feel for what's really going on underneath.
I think the questions you need to ask yourself are:
How soon do you plan to add Windows to your network programming repertoire, AND
Do you want your code to be cross-platform
If you want your code to be cross-platform, I'd look at Boost or some other cross-platform network library to get you there quickly. If you are simply wanting to start out learning about network programming in general and then add Windows network programming specifically to your skillset, I'd start with the BSD API as you've planned and then get a resource for specifically doing this for Windows when you are ready. When I made the move from Linux to Windows I found it was worth the extra time to learn the Windows way of doing things.
Even though you can use Windows API to do socket programming, I would recommend you learning BSD sockets API (or POSIX sockets API) and used it in BOTH: Windows and Linux.
Windows has great support for BSD sockets API.
And you will greatly benefit from a single code base instead of coding twice the same features. Besides, BSD/POSIX API is also available in many other UNIX flavors (MAC OS X, HP/UP, AI/X, BSD, you name it).
For simple apps, BSD sockets will work just fine in Windows. But for the bells and whistles, I really recommend reading up on "native" winsock. Asynchronous sockets are really nice in GUI apps, and Overlapped I/O is just the bee's knees if you want high speed performance, without having to deal with threads (you can if you want to, but Windows will do it for you).
This is a good read.
There's Network Programming for MS Windows. I haven't read this yet, but will definitely do it as it looks very promising.
Don't spend your money yet - I haven't personally found a better guide on networking than Beej's.
http://beej.us/guide/bgnet/
I have previously implemented server/client networking programs in C, but I have never done peer-to-peer program or any socket programming in C++.
For peer-to-peer, I guess I would have to create multiple threads and manage incoming and outgoing connections, since each program will work like a client and a server at the same time, right?
What would be a good way to implement this in C++? I believe C++ does not natively support threading...
You're not required to use multiple threads. An alternative is to use a single thread, and multiplex the sockets using select() (or poll() or epoll() or etc).
You might want to look into the boost.asio library which is good for multiple socket connctions (either threaded or not...)
Any code that would be valid in C is also valid in C++. So you can use the same socket API there and the same threading API (but the Boost wrappers might indeed be much more convenient).
Also C++ will natively support threading sometime towards the end of this year (the standard is already written and expected to be voted on by ISO later this year). Of course it may take some time to show up in your compiler/stdlibc++ (but gcc/gnu stdlibc++ already implements it except for language support for thread-local storage (which it does support, but using the older compiler-specific way)). For compilers that don't support it, the boost version is mostly compatible to the proposed standard anyway.
I'm going to try to explain what I mean using a few examples:
socket() -> WSASocket()
connect() -> WSAConnect()
send() -> WSASend()
sendto() -> WSASendTo()
recv() -> WSARecv()
recvfrom() -> WSARecvFrom()
...
closesocket() -> WSA???()
This is nothing that matters much, but is still something that gives me a splitting headache.
To understand this, you have to realize that Winsock was created in the early 1990s, back when the Windows 3.x dinosaur roamed the earth.
The Windows Sockets ("Winsock") API mirrors most of the BSD sockets API: where both provide a given function, both do the same thing. So, socket() is the same call under both APIs. There are minor differences in places, but nothing bigger than the differences in network programming for other systems based on BSD sockets, such as Linux and OS X.
In addition to implementing that common base API, the Winsock API also provides many extensions to BSD sockets. Many have names similar to the original functions, but with a WSA prefix and camel-case for everything else. These are purely extended versions of the original functions, not replacements for them. You pick which one to use depending on whether you need the extended functionality and whether your program has to be portable to systems that provide only the BSD sockets API. For instance, WSASocket() takes the same parameters as socket() plus three additional ones which have to do with other Winsock extensions. If you do not need the extensions, there is no real penalty to calling socket() instead, and you get a portability benefit besides.
In addition to these simple extensions, there are Winsock extensions that have no direct BSD equivalent, such as WSAAsyncSelect(). These generally have to do with differences in the way Windows programs are written, as compared to programs for Unixy systems. In this particular case, WSAAsyncSelect() exists to make it easier to write single-threaded GUI programs that use sockets without network I/O blocking the GUI or vice versa. This is useful today, but absolutely critical to Winsock's success back in the Windows 3.1 days, which didn't have threads or other useful multiprocessing and IPC mechanisms.
That leaves only a few oddballs like closesocket() and ioctlsocket().
closesocket() is the same as close(2) under POSIX/Unix, except that it only takes sockets, not file handles. That's part of the reason for the name change, but the real reasons come from that early-1990s history issue I brought up above. In those days, some Windows compilers — there were more available then than today — included POSIX API equivalents to ease porting code from other platforms to Windows. Such features were very limited, and didn't include sockets support, but nevertheless, the close() function name was considered "taken" on Windows at that time. It isn't true any more, but Winsock is a product of its history and can't be changed now.
The story for ioctlsocket() vs. ioctl() is similar. One big difference is that ioctlsocket() is greatly limited on Windows as compared to what ioctl() can do on a Unix system. It exists only to provide Windows with a few network-related facilities that the original Winsock creators thought useful in the BSD sockets API. Over the years, much of what you can do with sockets and ioctl() on Unixy systems but not with ioctlsocket() has been added to Windows through other APIs, just one of which is WSAIoctl().
I've written an article on "The History of Winsock" for the Winsock Programmer's FAQ (which I maintain) that goes into more detail on all this. Another relevant article is "BSD Sockets Compatibility."
closesocket is only available on Windows, I'm not sure why they didn't follow the WSA convention there though. If it really bothers you though you can make your own wrapper that calls closesocket.
As mentioned in WSASocket a call to closesocket should be made.
This is written in the MSDN documentation:
Renamed Functions
In two cases it was necessary to rename functions that are used in Berkeley Sockets in order to avoid clashes with other Microsoft Windows API functions.
Close and Closesocket
Sockets are represented by standard file descriptors in Berkeley Sockets, so the close function can be used to close sockets as well as regular files. While nothing in Windows Sockets prevents an implementation from using regular file handles to identify sockets, nothing requires it either. On Windows, sockets must be closed by using the closesocket routine. ON Windows, using the close function to close a socket is incorrect and the effects of doing so are undefined by this specification.
Ioctl and Ioctlsocket/WSAIoctl
Various C language run-time systems use the IOCTLs for purposes unrelated to Windows Sockets. As a consequence, the ioctlsocket function and the WSAIoctl function were defined to handle socket functions that were performed by IOCTL and fcntl in the Berkeley Software Distribution.
For the sake of completeness, one should notice that whether it was about networking, files, time / dates or any other part of the ANSI C / POSIX APIs, MICROSOFT has spent a great deal of energy to make sure that its proprietary generations of Windows APIs are incompatible with the Unix APIs (that existed far before Windows).
The same strategy is used by MICROSOFT with HTML (IE), HTTP (IIS), OpenDocuments (MS-Word), etc. so the usual excuse that it is accidental (or only motivated by the desire to 'innovate') is more than doubtful.
Look at how much C# is a (bad) copy of Java - while at the same time managing to be completely incompatible (the function names are very close if not identical, but the number of parameters -or their order- is different).
Now you know why you had to ask this question in the first place.
I need to make a connection through wireless or LAN. I have done this on Windows (VS2008 C#, Sockets), but not on Linux (Ubuntu 10.04). I have installed mono, and I can handle many things there, but it's speed is unacceptable for my 600MHz processor, so I decided to move on C++, but I'm new to C++ and I'm not familiar to many of it's headers. Is there any header or library which can do that for me?
How the actual connection is done (if wireless or cable) should be up to the system; if you want to use sockets, I suggest reading of beej guide to network programming , it contains everything (or so) you need to know. It's C mainly, but reusing it for C++ needs no effort.
Did you think about using boost::asio, this way you can share at least the code between linux & windows. The overhead is not that big compared to naked sockets and you have the benefit of better semantics. Many parts of code from boost have flown into standard C++ so the code is of rather high quality.