為讓 .NET 開發者深入理解 Winsock2 底層機制,本文將 .NET Socket 同步模型的核心 P/Invoke 封裝代碼剝離簡化,僅保留 TCP/IPv4、Win2000+ 環境下的同步伺服器邏輯,移除計數器、日誌、非同步/IOCP 相關代碼。
直接對應 ws2_32.dll 核心函數:
[SuppressUnmanagedCodeSecurity]
internal static class OSSOCK
{
[DllImport("ws2_32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern SocketError WSAStartup(short wVersionRequested, out WSAData lpWSAData);
[DllImport("ws2_32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern SafeCloseSocket.InnerSafeCloseSocket WSASocket(
AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType,
IntPtr protocolInfo, uint group, SocketConstructorFlags flags);
[DllImport("ws2_32.dll", SetLastError = true)]
internal static extern SocketError bind(SafeCloseSocket socketHandle, byte[] socketAddress, int socketAddressSize);
[DllImport("ws2_32.dll", SetLastError = true)]
internal static extern SocketError listen(SafeCloseSocket socketHandle, int backlog);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[DllImport("ws2_32.dll", SetLastError = true)]
internal static extern SocketError ioctlsocket(SafeCloseSocket socketHandle, int cmd, ref int argp);
[DllImport("ws2_32.dll", SetLastError = true)]
internal static extern unsafe int recv(IntPtr socketHandle, byte* pinnedBuffer, int len, SocketFlags socketFlags);
[DllImport("ws2_32.dll", SetLastError = true)]
internal static extern unsafe int send(IntPtr socketHandle, byte* pinnedBuffer, int len, SocketFlags socketFlags);
[DllImport("ws2_32.dll", SetLastError = true)]
internal static extern SocketError shutdown(SafeCloseSocket socketHandle, int how);
[DllImport("ws2_32.dll", SetLastError = true)]
internal static extern SocketError setsockopt(SafeCloseSocket socketHandle, SocketOptionLevel optionLevel, SocketOptionName optionName, ref int optionValue, int optionLength);
}
Socket 只是薄封裝,底層仍是這些 API。遇到網路疑難雜症時,抓 Dump 分析呼叫堆疊、觀察阻塞於哪個 API,能快速定位問題。本文提供的精簡代碼適合作為教學參考,生產環境建議直接使用 .NET 高層 Socket / TcpListener 或成熟網路庫。