赞
踩
- /*
- 一、使用winsock的一般步骤
- 1.包含winsock头文件
- #include<winsock2.h> 其头文件包含了windows.h
- 2.链接winsock导入库
- 2.1 配置属性-》链接器-》输入-》附加依赖项-》导入库名
- 2.2 预处理命令
- #pragma comment(lib,"ws2_32.lib")
- 3. 加载winsock动态链接库(调用winsock函数的前提)
- 需要使用wsastartup()函数,
- 返回值为一整数,0:成功, 失败时:
- #define WSAEFAULT 10014L
- // MessageId: WSAEINVAL
- // MessageText:
- // An invalid argument was supplied.
-
- #define WSAEINVAL 10022L
- // MessageId: WSAEMFILE
- // MessageText:
- // Too many open sockets.
- #define WSAEINPROGRESS 10036L
- // MessageId: WSAEALREADY
- // MessageText:
- // An operation was attempted on a non-blocking socket that already had an operation in progress.
- #define WSAEPROCLIM 10067L
- // MessageId: WSAEUSERS
- // MessageText:
- // Ran out of quota.
- #define WSASYSNOTREADY 10091L
- // MessageId: WSAVERNOTSUPPORTED
- // MessageText:
- // The Windows Sockets version requested is not supported.
- #define WSAVERNOTSUPPORTED 10092L
- // MessageId: WSANOTINITIALISED
- // MessageText:
- // Either the application has not called WSAStartup, or WSAStartup failed.
- WSAStartup(_In_ WORD wVersionRequested,_Out_ LPWSADATA lpWSAData);
- wVersionRequested:双字节类型,指明winsock库的版本号,高位字节:副版本 低位字节:主版本
- 常使用宏 MAKEWORD(a, b) 加载版本,a:副版本 b:主版本
- lpWSAData:返回winsock版本的详细信息,为一LPWSADATA结构体指针
- typedef struct WSAData {
- WORD wVersion; //winsock版本号
- WORD wHighVersion; //winsock库支持最高的winsock版本号
- #ifdef _WIN64
- unsigned short iMaxSockets;
- unsigned short iMaxUdpDg;
- char FAR * lpVendorInfo;
- char szDescription[WSADESCRIPTION_LEN+1];
- char szSystemStatus[WSASYS_STATUS_LEN+1];
- #else
- char szDescription[WSADESCRIPTION_LEN+1]; //加载winsock库说明
- char szSystemStatus[WSASYS_STATUS_LEN+1]; //状态和配置信息
- unsigned short iMaxSockets; //同时打开的winsock的最大数
- unsigned short iMaxUdpDg; //可发送udp数据报的最大字节数
- char FAR * lpVendorInfo; //厂商信息
- #endif
- } WSADATA, FAR * LPWSADATA;
- 4.注销winsock动态链接库
- 使用函数wsacleanup(void);
- 函数无参,成功返回0, 失败时返回socket_error 在winsock2.h中定义,对应值为-1
- 二、网络字节顺序(涉及储存时的大端顺序,小端顺序)
- 本地:主机字节序
- 网络收发:网络字节序
- u_short htons(_In_ u_short hostshort);->主机字节序转为网络字节序
- hostshort:待转换主机字节序无符号短整型
- 返回值:网络字节序的无符号短整型,调用失败返回sockrt_error,错误信息由wsagetlasterror()函数获取。
- u_short ntohs(_In_ u_short netshort);->网络字节序转为主机字节序
- netshort:待转换网络字节序数据
- 返回值:主机字节序数据,调用失败返回sockrt_error,错误信息由wsagetlasterror()函数获取。
- u_long htonl(_In_ u_long hostlong);//上面两个是16位数据,此处为32位数据
- u_long ntohl(_In_ u_long netlong);
- 三、网络地址表示
- 1.地址结构
- struct in_addr
- {
- union {
- struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b; //常用
- struct { USHORT s_w1,s_w2; } S_un_w;
- ULONG S_addr;
- } S_un;
- #define s_addr S_un.S_addr // can be used for most tcp & ip code
- #define s_host S_un.S_un_b.s_b2 // host on imp
- #define s_net S_un.S_un_b.s_b1 // network
- #define s_imp S_un.S_un_w.s_w2 // imp
- #define s_impno S_un.S_un_b.s_b4 // imp #
- #define s_lh S_un.S_un_b.s_b3 // logical host
- } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
- struct sockaddr_in
- {
- short sin_family; //地址族,ip协议对应为af_inet
- USHORT sin_port;//16位端口号,网络字节序
- IN_ADDR sin_addr; //32位ip地址,网络字节序
- CHAR sin_zero[8]; //保留位
- } SOCKADDR_IN, *PSOCKADDR_IN;
-
- struct sockaddr
- {
- u_short sa_family; //协议地址族
- CHAR sa_data[14]; // Up to 14 bytes of direct address.
- } SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
- 2.地址转换函数
- unsigned long inet_addr(_In_z_ const char FAR * cp);->点分十进制ip地址转换为32位无符号整数。
- char FAR * inet_ntoa(_In_ struct in_addr in);->结构变量中的长整型ip地址转换为点分十进制形式。
- INT inet_pton(
- _In_ INT Family,
- _In_ PCSTR pszAddrString,
- _When_(Family == AF_INET, _Out_writes_bytes_(sizeof(IN_ADDR)))
- _When_(Family == AF_INET6, _Out_writes_bytes_(sizeof(IN6_ADDR)))
- PVOID pAddrBuf
- );->点分十进制转换为32位网络字节序无符号长整型
- PCSTR inet_ntop(
- _In_ INT Family,
- _In_ const VOID * pAddr,
- _Out_writes_(StringBufSize) PSTR pStringBuf,
- _In_ size_t StringBufSize
- );
- 四、网络配置信息
- 1.主机名与ip地址
- int gethostname(_Out_writes_bytes_(namelen) char FAR * name,_In_ int namelen);->查询本地计算机名字
- name:缓冲区,存放主机名字。
- namelen:缓冲区大小
- struct hostent FAR *gethostbyname(_In_z_ const char FAR * name);-》根据主机名/域名查询ip地址,不支持ipv6
- name:所要查询的计算机名字/域名
- struct hostent
- {
- char FAR * h_name; /* official name of host
- char FAR * FAR * h_aliases; /* alias list
- short h_addrtype; /* host address type
- short h_length; /* length of address
- char FAR * FAR * h_addr_list; /* list of addresses
- #define h_addr h_addr_list[0] /* address, for backward compat
- };
- INT getaddrinfo(
- _In_opt_ PCSTR pNodeName, //指向主机名的指针
- _In_opt_ PCSTR pServiceName, //指定查询端口号的服务名称或字符串形式的端口号
- _In_opt_ const ADDRINFOA * pHints,
- _Outptr_ PADDRINFOA * ppResult
- );-》根据主机名/域名查询ip地址,支持ipv6,#include"ws2tcpip.h"
- struct hostent FAR * gethostbyaddr(
- _In_reads_bytes_(len) const char FAR * addr, //指向网络字节序ip地址的指针
- _In_ int len, //地址的长度
- _In_ int type //ip地址对应的类型
- );-》根据ip查询相关信息
- 2.服务器查询
- struct servent FAR *getservbyname(
- _In_z_ const char FAR * name, //指向服务名的指针
- _In_opt_z_ const char FAR * proto //指向协议名的指针(可选)
- );->根据给定的服务名和所使用的协议名获取服务的端口号信息
- struct servent
- {
- char FAR * s_name; /* official service name 服务名
- char FAR * FAR * s_aliases; /* alias list 服务别名队列
- short s_port; /* port # 连接该服务的端口号,以网络字节序排序
- char FAR * s_proto; /* protocol to use 使用该服务的所用的传输协议名
- };
- struct servent FAR * getservbyport(
- _In_ int port, //给定的端口号,以网络字节序排序
- _In_opt_z_ const char FAR * proto //指向传输协议名的指针,可以为空。
- );-》根据给定的协议和端口号查询服务名称等信息
- */
-
- //例:查询本机名称及ip(c++ vs2017)
-
- #include<iostream>
- #include"WinSock2.h"//包含winsock库头文件
- #include"ws2tcpip.h"
- #pragma comment(lib,"ws2_32.lib")//链接winsock导入库
- using namespace std;
-
- int main()
- {
- //加载winsock DLL
- WSADATA wsaData;
- if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
- {
- cout << "加载winsock DLL失败..." << endl;
- return 0;
- }
- char hostname[256];
- if (gethostname(hostname, sizeof(hostname)))
- {
- cout << "获取主机名字失败..." << endl;
- WSACleanup();
- return 0;
- }
- cout << "本机名字为:" << hostname << endl;
- //根据主机名字查询主机ipv4地址
- struct addrinfo hints, *p_addrinfo, *p;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;//ipv4地址
- unsigned int retval = getaddrinfo(hostname, NULL, &hints, &p_addrinfo);
- if (retval != 0)
- {
- cout << "get addrinfo failed with error: " << int(retval) << endl;
- WSACleanup();
- return 1;
- }
- //输出ip地址
- p = p_addrinfo;
- cout << "本机ip地址为: ";
- char ipaddr[20];
- in_addr addr;
- while (p != NULL)
- {
- addr = ((sockaddr_in*)(p->ai_addr))->sin_addr;
- cout << inet_ntop(AF_INET, (void*)&addr, ipaddr, 20) << endl;
- p = p->ai_next;
- }
- WSACleanup();
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。