Sockets in MinGW - c++

I was just trying to build netcat in MSYS using MinGW and realized that MinGW never really ported all of the BSD socket stuff to Windows (eg sys/socket.h). I know you can use Windows Sockets in MinGW, but why did they never make a Windows port of the BSD sockets? I noticed quite a few programs using #ifdef's to workaround the issue. Is there a Windows port of the BSD sockets somewhere that can be used instead?
Here are the errors when doing a make for netcat in MSYS:
gcc -DLOCALEDIR=\"\/usr/local/share/locale\" -DHAVE_CONFIG_H -I. -I. -I.. -g -O2 -Wall -c `test -f 'core.c' || echo './'`core.c
In file included from core.c:29:
netcat.h:38:24: sys/socket.h: No such file or directory
netcat.h:39:63: sys/uio.h: No such file or directory
netcat.h:41:24: netinet/in.h: No such file or directory
netcat.h:42:55: arpa/inet.h: No such file or directory
There are no #ifdef's for MinGW. Is there a library/package I can add to MSYS to make everything compile without errors?
Note: You can download netcat here and browse the CVS repo here

BSD sys/socket.h is a POSIX header and the win32 API doesn't support it. MinGW headers are just a reimplementation of native win32 headers and don't offer additional POSIX compatibility.
If you are looking for sys/socket.h support, try either GNU gnulib's sys/socket.h replacement or go with Cygwin, which provides a POSIX compatibility wrapper on Windows.

WinSock and WinSock2 have different function names from the BSD Sockets. If I wish to write cross-platform applications, then I have code a lot of work-arounds just to keep Microsoft happy.
It would be so much easier if there were special "socket.h" and "socket.c" files included with MinGW that simply translated stuff by calling the respective WinSock2 counter-parts.
I'm just starting to learn C programming, so I'm unable to do this myself, but I'm surprised that nobody seems to have even attempted this so far.

These comments from another answer served as the answer I needed to get a piece of simple bsd socket code to compile with mingw on windows.
Replace all of those includes with #include as that would
be the equivalent header for winsock, then see what happens.
You will also need to link against ws2_32 and use
WSAStartup/WSACleanup. Which might get you up and running.
EDIT:
I also ended up having to replace close with shutdown / closesocket and write with send.
The code compiled fine but didn't actually work without those additional changes.

As ChrisW said, Winsock2 is a port of BSD sockets. Which part of winsock are you trying to use which differs from BSD sockets ? (other than the WSAStartup and WSACleanup)

MingWin is minimalist, and that is the most important aspect of it. Because it makes it easier to understand, at the end it is the developer's responsibility to write the application. MingWin only makes things easier but does no magic in turing nix apps to windows.

See the stackoverflow link : Where does one get the "sys/socket.h" header/source file?
The answer/solution is more explicit.

Related

Winlibs and libcurl

I am asking here because I couldn't get any support elsewhere. Also consider that I am quite a beginner so bear patience.
I am using Winlibs (winlibs.com, a ready to use mingw gcc10+ distribution) to code under Windows because after having tried other alternatives I judged it the best to my purposes, easiest to install and the most functional. I never had any problems with it.
But recently I had the need of writing some simple code to send a POST request. I wanted to do it in a possibly portable and c++ friendly manner, so I was suggested to use Curl. No libcurl is included in winlibs so I tried to load one from here
https://curl.se/download.html
I chose the windows 64 binary of course (7.83.1) since I am working on windows 64 with winlibs 64. I installed everything in the right place and linked against libcurl.a.
Unfortunately the linker complains of unresolved symbols so I have to supppose the curl binaries I used are not suitable.
How can I use libcurl with winlibs then ? Before bothering here I really googled but could find no info!
The MinGW-w64 tools from https://winlibs.com/ are only a build toolchain, so they don't contain libraries for you to link with (yet).
You need a Windows build of libcurl and use that.
To use it you must include the location to the header files using the -I compiler flag, and then link with the library by pointing to the location of the .a file with the -L linker flag and then link with the library using the -l flag (-lcurl in this case). If you don't have .a files you can also try to link with the full path of the .dll file and gcc will know it's a shared library.
An easier way is to get libcurl via MSYS2's pacman package manager.
If you want to statically link you need to use the output of pkg-config --static --libs libcurl as link flags.
In practice though I noticed that sometomes pkg-config --static --libs libcurl is missing some dependencies and you still need to add some manually. An example of a project of mine that builds on Windows with winlibs MinGW-w64 (both 32-bit and 64-bit) can be found at https://github.com/brechtsanders/winlibs_tools/blob/main/Makefile (specifically look for the definition of CURL_LDFLAGS)

Needed info for libcurl, cross-platform

I want to implement an auto-update or update notification method for my open-source project. My searches often lead me to libcurl.
I search much about HTTP-libs - and many times I ended up with libcurl ... but can I use it for Linux and Windows together?
My wish is to include only header-files (same header for Linux & WIndows, if possible) and add only OS-spefic lib flags with cmake or visual-studio project files. That way, I can compile the same code on both platforms.
Is that possible in general with libcurl? If yes, how do I do that directly?
Yes you can.
An application can use libcurl on both Linux and Windows with the source code parts that do the HTTP transfers being identical. libcurl provides the same API and it works the same on a vast amount of different operating systems.

Socket programming confusion with windows and unix/linux

Hello I am trying socket programming in c++. I need confirmation or say rejection for this logic. I think socket.h header files are designed for UNIX systems whereas for Windows everything is done with winsock.h.
Is this correct?
For windows, you need winsock2.h and ws2tcpip.h.
On Linux, you need sys/socket.h and sys/types.h for the socket functions and netinet/in.h for the IP related structs.
Some other differences:
Windows uses SOCKET for socket descriptors while Linux uses int
Windows has closesocket() to close sockets, while Linux uses close()
On Windows, you need to call WSAStartup() before calling any socket functions, and WSACleanup() when you are done using sockets.
On Linux, you can print errors from socket functions using perror() or strerror(). On Windows, you have to call WSAGetLastError() to get the error code and FormatMessage to get the error text.
Most platforms implement a BSD-compatible socket API, however different platforms do use different .h files to declare their API. So, to answer your question, Yes, Windows uses winsock.h (and winsock2.h), whereas POSIX-based platforms like Unix/Linux use sys/socket.h instead (socket.h is defined as part of the POSIX standard, but Windows is not a POSIX-compatible platform). If you want to write cross-platform code, you have to take this into account. As well as other differences, which #dbush outlined in his answer.
Every header file starting with "sys/..." is designed for UNIX environment. As for windows, they tend to use "win" as a prefix to every header file they use.
If you are interested in windows sockets (winsocks) i guess you should start from here.
As for UNIX sockets, this site seems very interesting and easy going :)

Unable to open the socket program header in VS2008

idevs.h, netinet/in_systm.h, netinet/ip.h, netinet/tcp.h openssl/ssl.h sys/socket.h
These header files can work in Linux but in visual studio 2008 compile error says unable to open header file. These are socket program related headers. (I am unable to get any proper result from web search)
Problem:
Please let me know any dll I have include for these headers or any other equivalent headers are available ?
Thanks in advance.
In windows environment you need to include the windows specific headers like winsock.h and others (http://msdn.microsoft.com/en-us/library/windows/desktop/ms738545(v=vs.85).aspx). You need to switch between headers using the #ifdef statements when doing builds for different platforms.
Nobody ever promised that windows implementation of the sockets concept is 100% identical to the one of Unix. These implementations have a lot in common, but differences are also present.
Sockets are not part of the C++ standard and are implemented in different ways in Linux and Windows. That means, that the native socket libraries are different in both OSes, and Windows has other headers for its socket API than Linux. So you will not only have to include other headers but might also need to use other functions.
Depending on what you want to achieve, you might want to use a library that wraps the OS specific parts and provides a portable interface. There are several more or less portable networking libraries, one of the best known might be Boost.Asio

Help on Porting a SIP library to PSP

I'm currently trying to port a SIP stack library (pjSIP) to the PSP Console (using the PSPSDK toolchain), but I'm having too much trouble with the makefiles (making the proper changes and solving linking issues).
Does anyone know a good text, book or something to get some insight on porting libraries?
The only documentation this project offers on porting seems too dedicated to major OS's.
Look at other libraries that were ported over to the PSP. Doing diffs between a linux version of a library, and a PSP version should show you.
Also, try to get to know how POSIX compatible the PSP is, that will tell you how big the job of porting the library over is.
The PSP is not UNIX and is not POSIX compliant, however the open source toolchain is composed by gcc 4.3, bintutils 1.16.1 and newlib 1.16.
Most of the C library is already present and can compile most of your code. Lots of libraries have been ported just by invoking the configure script with the following arguments:
LDFLAGS="-L$(psp-config --pspsdk-path)/lib -lc -lpspuser" ./configure --host psp --prefix=$(pwd)/../target/psp
However you might need to patch your configure and configure.ac scripts to know the host mips allegrex (the PSP cpu), to do that you search for a mips*--) line and clone it to the allegrex like:
mips*-*-*)
noconfigdirs="$noconfigdirs target-libgloss"
;;
mipsallegrex*-*-*)
noconfigdirs="$noconfigdirs target-libgloss"
;;
Then you run the make command and hope that newlib has all you need, if it doesn't then you just need to create alternatives to the functions you are missing.
Porting is very platform specific, so I don't think you will find much general literature on the subject.
Off the top of my mind, some things you may encounter:
endianness
word size
available libraries
compiler differences
linker differences (you've already seen that one)
peripheral hardware differences
...
I did some more research and found this post at ps2dev forum:
The PSP is not a Unix system, and the pspsdk is not POSIX compliant. It's close in some places, but you can't expect to just take any code that compiles fine on a POSIX system and have it work. For example:
pspsdk uses newlib, which lacks some of glibc's features and headers.
libc is not linked by default, so typical autoconf tests will fail to build
autoconf knows nothing about the PSP
defining PSP_MODULE_INFO and running psp-fixup-imports on the executable are required, otherwise it won't run
You should look at all of the other libraries and programs that have been ported (in the psp and pspware repositories). All SDL libs use autoconf, for example.
I think this delivers more detail into what I was looking for, and also show the #[Jonathan Arkell] point of looking into libraries that already been ported.
Thanks for your replies.