Winsock编程基础1
1、加载和释放Winsoke库
//所有Winsock函数都是从WS2_32.DLL导出,包含相应库文件
#include <winsock2.h>
#pragma comment(lib, "WS2_32")
//若没有加载,调用scok函数返回的SOCKET_ERROR出错代码为WSANOTINITIALISED int WSAStartup( WORD wVersionRequested, //指定要加载的Winsock库版本,高字节次版本, 低字节主版本号,使用MAKEWORD(x, y) LPWSADATA lWSAData //一个指向WSADATA结构的指针,用来返回DLL库的详细信息 ); typedef struct WSAData { WORD wVersion; //库文件建议应用程序使用的版本 WORD wHighVersion; //库文件支持的最高版本 char szDescription[WSADESCRIPTION_LEN+1];//库描述字符串 char szSystemStatus[WSASYS_STATUS_LEN+1];//系统状态字符串 unsigned short iMaxSockets; //同时支持的最大套接字数量 unsigned short iMaxUdpDg; //废弃 char FAR * lpVendorInfo; //废弃 } WSADATA, FAR * LPWSADATA; //成功返回0,否则要调用WSAGetLastError函数查看原因
int WSACleanup(void)
简单封装
class CInitSock { public: CInitSock(BYTE minorVer = 2, BYTE majorVer = 2) { //初始化WS2_32.DLL WSAADATA wsaData; WORD sockVersion = MAKEWORD(minorVer, majorVer); if(::WSAStartup(sockVersion, &wsaData) != 0) exit(0); } ~CInitSock() { ::WSACleanup(); } }
Winsock寻址和字节顺序
//版本1使用sockaddr兼容 struct sockaddr { u_short sa_family; /* address family */ char sa_data[14]; /* up to 14 bytes of direct address */ }; //我们一般使用TCP/IP,所以上面的TCP/IP版本为 struct sockaddr_in { short sin_family; //地址族(即指定地址格式),AF_INET(IP地址) u_short sin_port; //端口号(不要使用0-1023以免影响公共服务) struct in_addr sin_addr; //IP地址(32位) char sin_zero[8]; //空字节, 设为0, 为了与sockaddr兼容 }; //IP地址 in_addr结构 struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; //4个u_char描述 struct { u_short s_w1,s_w2; } S_un_w; //2个u_short描述 u_long S_addr; //1个u_long描述 } S_un; //IP地址函数 unsigned long inet_addr(const char *cp) //将点分十进制IP地址字符串转换为32位二进制表示IP地址,二进制数按网络顺序存储 char* inet_ntoa(struct in_addr) //将32位二进制数转换为字符 //网络字节顺序为大端顺序(高字节低位), Intel为小端顺序(高字节高位) u_short htons(u_short hostshort) //主机顺序转网络字节顺序 u_long htonl(u_long hostlong) // u_short ntohs(u_short hostshort) //网络字节顺序转主机顺序 u_long ntohl(u_long hostlong)
初始化sockaddr_in
sockaddr_in sockAddr; sockAddr.sin_family = AF_INET; sockAddr.sin_port = htons(6789); sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); //或使用下列初始化IP地址 sockAddr.sin_addr.S_un.S_un_b.s_b1 = 127; sockAddr.sin_addr.S_un.S_un_b.s_b2 = 0; sockAddr.sin_addr.S_un.S_un_b.s_b3 = 0; sockAddr.sin_addr.S_un.S_un_b.s_b4 = 1;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix