windows网络编程基础学习(1)

/*
一、使用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;
}

 


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值