1.WinSock的初始化
#include<iostream>
#include<WinSock2.h>
#include<MSWSock.h>
#pragma comment(lib, "WS2_32.lib")//使用WinSock2.h时,须加载此项
using namespace std;
//Winsock2函数带有WSA前缀,除了WSAStartup WSACleanup WSARecvEX WSAGetLastError
int main()
{
WSADATA wsData;
if (SOCKET_ERROR == WSAStartup(MAKEWORD(2, 2), &wsData))//第一个2是次版本号
{
cout << "初始化错误!" << endl;
}
cout << "主版本号:" << (int)LOBYTE(wsData.wHighVersion) << endl;//所能支持的最高版本信息
cout << "次版本号" << (int)HIBYTE(wsData.wHighVersion) << endl;
WSACleanup();
system("pause");
return -1;
}
2.错误检查和处理
WSAGetLastError
WSASetLastError手动设置错误代码
3.
typedef struct sockaddr_in {
ADDRESS_FAMILY sin_family;
USHORT sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;
sin_family必须是AF_INET,作用是告知WinSock使用的是IP地址族
sin_zero[8]只充当填充项,使SOCKADDR_IN和SOCKADDR结构长度一样.SOCKADDR是一个通用的套接字地址,作用相当于void*。
字节排序
不同计算机处理器可能采用big-endian或little-endian形式进行编码。Internet联网标准指定多字节值必须用big-endian形式表示,一般称之为网络字节顺序。
下面4个常用API函数便将一个数从主机字节顺序转换为网络字节顺序:
WSAHtonl//4字节
htonl
WSAHtons//2字节
htons
反之
WSANtohl
ntohl
WSANtohs
ntohs
另一个常用的函数将点分IP地址转换为4字节整数
srvAddr.sin_addr.S_un.S_addr = inet_addr(“127.0.0.1”);
SOCKADDR_IN srvAddr;
srvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
srvAddr.sin_family = AF_INET;
srvAddr.sin_port = htons(DefaultPort);
INADDR_ANY代表所有发送到服务器的这个端口,不管是哪个网卡 / 哪个IP地址接收到的数据,都交给这个套接字处理。