
In this story
If you are building a Windows application that includes both winsock2.h and windows.h, you have probably seen a wall of redefinition errors for sockaddr, fd_set or timeval. The cause is simple: windows.h pulls in the legacy winsock.h header (Windows Sockets 1.1), and its declarations clash with those in winsock2.h.
Why the headers clash
windows.h, the master header for the Windows API, includes the old Winsock 1.1 declarations from winsock.h unless told not to. winsock2.h declares the same structures again, so if windows.h comes first, the compiler meets every structure twice.
That is why include order matters: winsock2.h has to be seen before windows.h can pull in winsock.h. For a typical Winsock 2 application today, the cleanest fix is to stop that legacy inclusion altogether.
The fix: WIN32_LEAN_AND_MEAN
If you can work without windows.h, do it. #include <winsock2.h> and nothing else, then link against Ws2_32.lib. But in many applications, you'll still need windows.h to access the full Windows API. In that case, the fix is to prevent it from including winsock.h at all by defining WIN32_LEAN_AND_MEAN before #include <windows.h>. winsock2.h can then be included after it without conflict. Including winsock2.h before windows.h works too.
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
Some projects define _WINSOCKAPI_ instead, which is the include guard winsock.h itself checks. It works, but it relies on an internal detail; WIN32_LEAN_AND_MEAN, or simply including winsock2.h before windows.h, is cleaner. In projects with a precompiled header, put winsock2.h there, ahead of anything that might include windows.h.
What the errors look like
The errors usually name the structures declared in both headers. In Visual C++ they look like error C2011: 'sockaddr': 'struct' type redefinition, often followed by C2375 errors (redefinition; different linkage) for functions such as accept or bind.
Linking is a separate step. The header fix removes the redefinition errors, but you still need to link Ws2_32.lib, through the linker settings or the #pragma comment line above, or you will get unresolved externals instead.
Why it still happens
The problem survives because windows.h still carries Winsock 1.1 compatibility for old code, and any header that includes windows.h before yours can trigger it.
If you hit these redefinition errors, define WIN32_LEAN_AND_MEAN before windows.h, or include winsock2.h first, and link Ws2_32.lib.


