Winsock有两个版本,Winsock1 和 Winsock2 现在开发网络应用程序都使用Winsock2,需要在程序中包含头文件winsock2.h, 它包含了绝大部分socket函数和相关结构类型的声明和定义。同时要添加的还有到Ws2_32.lib库的链接。包含必要的头文件,设置好链接环境之后,便可进行下面的编码工作了。
1.1 Winsock库的装入和释放
每个Winsock应用程序必须加载相应版本的Winsock DLL。 如果在调用Winsock函数前没有加载Winsock库,函数返回SOCKET_ERROR, 出错代码将是WSANOTINITIALISED。加载Winsock库的函数是WSAStartup, 其定义如下:
int WSAStartup(
WORD wVersionRequested, // 指定想要加载的Winsock库的版本,高字节为次版本号,低字节为主版本号
LPWSADATA lpWSAData // 一个指向WSADATA结构的指针, 用来返回DLL库的详细信息
);
wVersionRequested参数用来指定想要加载的Winsock库的版本。 为了建立此参数的值,可以使用宏MAKEWORD(x,y), 其中x是高字节,y是低字节。
lpWSAData 是一个指向LPWSADATA结构的指针,WSAStartup使用所加载库的版本信息填充它。
typedef struct WSAData
{
WORD wVersion; // 库文件建议应用程序使用的版本
WORD wHighVersion; // 库文件支持的最高版本
char szDescription[WSADESCRIPTION_LEN + 1]; // 库描述字符串
char szSystemStatus[WSASYS_STATUS_LEN + 1]; // 系统状态字符串
unsigned short iMaxSockets; // 同时支持的最大套接字的数量
unsigned short iMaxUdpDg; // 2.0版中已废弃的参数
char FAR* lpVendorInfo; // 2.0版中已废弃的参数
} WSADATA, FAR* LPWSADAA;
函数调用成功返回0. 否则要调用WSAGetLastError函数查看出错的原因。 此函数的作用相当于API函数GetLastError, 它取得最后发生错误的代码。
每一个对WSAStartup的调用必须对应一个对WSACleanup的嗲用, 这个函数释放Winsock库。
int WSACleanup(void);
所有的Winsock函数都是从WS2_32.DLL导出的, VC++在默认情况下并没有链接到该库, 如果想使用Winsock API, 就必须包含相应的库文件。
#pragma comment(lib,"WS2_32")
1.2 封装的CinitSock类
文件名initsock.h
#include <WinSock2.h>
#pragma comment(lib, "WS2_32")
class CInitSock
{
public:
CInitSock(BYTE minorVer = 2, BYTE magorVer = 2)
{
// 初始化WS2_32.dll
WSADATA wsaData;
WORD sockVersion = MAKEWORD(minorVer, magorVer);
if ( ::WSAStartup(sockVersion, &wsaData) != 0)
{
exit(0);
}
}
~CInitSock()
{
::WSACleanup();
}
};