- 一、不带参宏定义
- 二、结构体(带参宏定义)
- WSADATA structure">1.WSADATA structure
- HOSTENT structure">2. HOSTENT structure
- SOCKADDR_IN structure">3.SOCKADDR_IN structure
- 二、部分API函数
一、不带参宏定义
WORD
函数源码:
// 宏定义typedef unsigned short WORD; // 相当于是一个无符号短整型变量
使用示例:
配合宏定义MAKEWORD()使用
WORD myWordVersion = MAKEWORD(2, 2); // MAKEWORD(2,2) 参数用于在系统上请求 Winsock 2.2 版本// 前面2是高字节记录,后面2是低字节记录
二、结构体(带参宏定义)
1.WSADATA structure
源码:
typedef struct WSAData {WORD wVersion;WORD wHighVersion;#if ...unsigned short iMaxSockets;#if ...unsigned short iMaxUdpDg;#if ...char *lpVendorInfo;#if ...char szDescription[WSADESCRIPTION_LEN + 1];#if ...char szSystemStatus[WSASYS_STATUS_LEN + 1];#elsechar szDescription[WSADESCRIPTION_LEN + 1];#endif#elsechar szSystemStatus[WSASYS_STATUS_LEN + 1];#endif#elseunsigned short iMaxSockets;#endif#elseunsigned short iMaxUdpDg;#endif#elsechar *lpVendorInfo;#endif} WSADATA;
功能:
用于存储被WSAStartup函数调用后返回的 Windows Sockets数据。它包含Winsock.dll执行的数据。
2. HOSTENT structure
源码:
typedef struct hostent {char *h_name;char **h_aliases;short h_addrtype;short h_length; //主机IP地址字节长度,对于IPv4是四字节,即32位char **h_addr_list;} HOSTENT, *PHOSTENT, *LPHOSTENT;
结构体成员变量:
- h_name- 主机 (PC) 的正式名称。如果使用 DNS 或类似的解析系统,则是完全限定域名 (FQDN) 导致服务器返回回复。如果使用本地主机文件,则它是 IPv4 地址之后的第一个条目。- h_aliases- 以**NULL**结尾的备用名称数组。- h_addrtype- 返回IP地址类型- h_length- 每个地址的长度- h_addr_list- 以**NULL**结尾的主机地址列表。地址以网络字节顺序返回。- ⭐兄台兄台,前方高能🚨:注意**h_addr_list**的返回存储格式是网络字节顺序。千万不要直接用printf带%s参数来打这个东西,会有问题的哈。所以到真正需要打印出这个IP的话,需要调用**inet_addr()或inet_ntoa()**。
简要描述:
配合gethostbyaddr 和 gethostbyname函数使用,gethostbyaddr 和 gethostbyname 函数返回一个hostent的指针,该结构是由 Windows 套接字分配的结构。hostent 结构包含成功搜索 name 参数中指定的主机的结果。
3.SOCKADDR_IN structure
源码:
typedef struct sockaddr_in {#if(_WIN32_WINNT < 0x0600)short sin_family;#else //(_WIN32_WINNT < 0x0600)ADDRESS_FAMILY sin_family;#endif //(_WIN32_WINNT < 0x0600)USHORT sin_port;IN_ADDR sin_addr;CHAR sin_zero[8];} SOCKADDR_IN, *PSOCKADDR_IN;
结构体成员变量:
- **sin_family:**- 传输地址的地址族。此成员应始终设置为 AF_INET。- **sin_port:**- 传输协议端口号。- **sin_addr:**- 包含 IPv4 传输地址的 [IN_ADDR](https://docs.microsoft.com/en-us/previous-versions/windows/hardware/drivers/ff556972(v=vs.85)) 结构。- **sin_zero[8]:**- 保留供系统使用。WSK 应用程序应将此数组的内容设置为零。
高能注意:
⭐除地址族外,SOCKADDR_IN 结构中的所有数据都必须以网络字节顺序(大端)指定。
简要描述:
SOCKADDR_IN 结构体为 AF_INET 地址族指定传输地址和端口 。
二、部分API函数
1.WSAStartup( )——进行相应的socket库绑定
简要描述:
初始化 Windows Sockets DLL,该函数是网络程序中最先使用的Windows Socke 函数,其它函数都要在WSA Startup调用成功之后才能正常运行。
源码:
int WSAStartup(WORD wVersionRequired,LPWSADATA lpWSAData);
函数参数:
- ***wVersionRequested:**Windows Sockets API提供的调用方可使用的最高版本号。高位字节指出副版本(修正)号,低位字节指明主版本号。- ***lpWSAData:**指向WSADATA数据结构的指针,用于接收 Windows Sockets 实现的详细信息。
函数返回值:
如果函数WSAStartup()执行成功,返回0;否则返回相应的错误代码。
2.WSACleanup( )
简要描述:
完成Windows Sockets 的使用之后,应用程序或DLL必须调用WSACleanup()将其从Windows Sockets的实现中注销,实现资源的释放。(与WSAStartup成对出现)
源码:
int WSACleanup();
函数返回值:
如果操作成功,则返回值为零。否则,返回值 SOCKET_ERROR,并且可以通过调用WSAGetLastError检索特定的错误编号 。
3.WSAGetLastError( )
简要描述:
获得上次操作失败的错误号。
源码:
int WSAAPI WSAGetLastError();
返回值:
返回值指示此线程上次失败的 Windows 套接字操作的错误代码。
4.gethostname( )
简要描述:
从本地获取标准券的主机名。
源码:
#define WSAAPI FAR PASCALint WSAAPI gethostname(_Out_writes_bytes_(namelen) char FAR * name,_In_ int namelen);
参数:
- ***name:**指向接收本地主机名的缓冲区的**指针**。 👉 _引用传递_- ***namelen:**指向的缓冲区的**长度**(以字节为单位)。
返回值:
如果没有发生错误,gethostname返回零。否则,它返回 SOCKET_ERROR 并且可以通过调用WSAGetLastError检索特定的错误代码(错误代码可以通过WSAGetLastError()函数获得) 。
5.gethostbyname( )
简要描述:
通过主机名获得主机信息。(👉主机名通过gethostname( )函数获得)
源码:
#include <netdb.h>extern int h_errno;struct hostent {char *h_name; /* 查询主机的规范名字 */char **h_aliases; /* 别名 */int h_addrtype; /* AF_INET */int h_length; /* 4 */char **h_addr_list; /* IPv4地址 */}struct hostent *gethostbyname(const char *name);
参数:
- ***name:**传入由[gethostname( )](#quQv9)函数获得的结果,或者自己设置输入主机名OR域名。
返回值:
gethostbyname将返回一个指向上述hostent结构的指针 。如果发生错误,它会返回一个空指针,并且可以通过调用WSAGetLastError来检索特定的错误编号。
示例代码:
#include <iostream>#include <WinSock2.h>#pragma comment(lib,"ws2_32.lib")using namespace std;int main() {WORD myWordVersion = MAKEWORD(2,2); // WORD ——> typedef unsigned short WORD; 相当于是一个无符号短整型变量// 创建的 WinSocket 版本 2.2WSADATA wsaData;char hostname[255];int startErr; // 函数调用错误返回值检测WSAStartup(myWordVersion, &wsaData);LPHOSTENT pHost;SOCKADDR_IN addrInfos;gethostname(hostname,sizeof(hostname));pHost = gethostbyname(hostname);printf("主机名:%s\n",pHost->h_name);printf("IP地址类型:%d\n", pHost->h_addrtype);printf("地址长度:%d\n", pHost->h_length);for (int n = 0; pHost->h_addr_list[n]; n++) {memcpy(&addrInfos.sin_addr, pHost->h_addr_list[n], pHost->h_length); // 将pHost结构体指针中的h_addr_list依次拷贝到// 标准的ip地址标准结构体SOCKADDR_IN中方便后续函数的处理cout << inet_ntoa(addrInfos.sin_addr) << endl;}WSACleanup();return 0;}
6.gethostbyaddr( )
简要描述:
根据网络地址获取主机信息
源码:
hostent *WSAAPI gethostbyaddr(const char *addr,int len,int type);
参数:
- ***addr:**所学要解析的地址- ***len:**IPV4 地址长度为4个字节- ***type:**地址类型为 AF_INET
返回值:
gethostbyaddr 会返回一个指向hostent结构的指针 。如果执行错误,它返回一个空指针,并且可以通过调用WSAGetLastError来检索特定的错误代码 。
7.memset( )
简要描述:
源码:
void *memset(void *dest,int c,size_t count // size_t 是无符号整数类型);
参数:
- ***dest:**指向要填充的字符串- ***c:**要设置的值。该值以int类型传递,但该函数使用该值的无符号字符转换来填充内存块。- ***count:**要设置为值的字节数。size_t 是无符号整数类型。(配合sizeof函数使用)
8.memcpy( )
简要描述:
复制内存块
源码:
void *memcpy(void *dest,const void *src,size_t count // size_t 是无符号整数类型);
参数:
- *dest:指向要复制内容的目标数组的**指针**,类型转换为void*类型的指针。- *src:指向要复制的数据源的**指针**,类型转换为const void*类型的指针。- *count:要复制的字节数。(配合sizeof函数使用)
补:⭐strcpy和memcpy的区别:
strcpy和memcpy都是标准C库函数。
- **复制的内容不同**。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。- **复制的方法不同**。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。_memcpy则是根据其第3个参数决定复制的长度。_- **用途不同**。通常在复制字符串时用strcpy,而需要复制其他类型数据时一般用memcpy。
9.getprotobyname( )
简要描述:
检索对应于协议名称的协议信息。
源码:
typedef struct protoent {char *p_name; // 协议的正式名称。如:TCP、UDP……char **p_aliases; // 以空字符结尾的备用名称数组。short p_proto; // 协议编号,以主机字节顺序排列。} PROTOENT, *PPROTOENT, *LPPROTOENT;// 该protoent结构包含名称和协议号对应于一个给定的协议名称。// 应用程序绝不能尝试修改此结构或释放其任何组件。此外,每个线程仅分配此结构的一个副本,// 因此,应用程序应在发出任何其他 Windows 套接字函数调用之前复制它需要的任何信息。protoent * getprotobyname( const char *name );
参数:
- *name:- 指向以空字符结尾的协议名称的指针。
返回值
如果没有错误发生, getprotobyname返回一个指针 protoent。否则,它会返回一个空指针,并且可以通过调用WSAGetLastError来检索特定的错误编号 。
10.getservbyname( )
简要描述:
检索与服务名称和协议相对应的服务信息。
源码:
typedef struct servent {char *s_name; // 服务的官方名称。char **s_aliases; // 以NULL结尾的备用名称数组。#if ...char *s_proto; // 联系服务时使用的协议名称。#if ...short s_port; // 可以联系服务的端口号。端口号以网络字节顺序返回。#elseshort s_port;#endif#elsechar *s_proto;#endif} SERVENT, *PSERVENT, *LPSERVENT; // 存储或某项服务的名称返回名称和服务号码。servent *WSAAPI getservbyname(const char *name,const char *proto);
参数:
- ***name**:- 指向以空字符结尾的服务名称的指针。- ***proto**:- 指向以空字符结尾的协议名称的指针。 如果此指针为 NULL,则 getservbyname 函数返回第一个服务条目,其中 name 与servent 结构的s_name 成员或servent 结构的s_aliases 成员匹配。 否则, getservbyname 匹配名称和原型。
返回值
如果没有发生错误, getservbyname 会返回一个指向servent结构的指针 。否则,它会返回一个空指针,并且可以通过调用WSAGetLastError来检索特定的错误编号 。
11.模板
简要描述:
参数:**
返回值:
