Windows 网络编程
2024-10-11 12:06:37
网络编程 API ,失败返回 -,错误代码 WSASYSNOTREADY 表示基础网络子系统没有准备好网络通行,WSAVERNOTSUPPORTED 表示 Socket 版本不支持,WSAEINPROGRESS 表示一个阻塞的 Sockets 操作在进程中,WSAEPROCLIM 表示 Sockets 支持的任务数到达上限,WSAEFAULT 表示 lpWSAData 不是一个有效指针 WORD MAKEWORD( X, Y ); 获得 wVersionRequested 正确值,WinSock 库版本,高位指定副版本,低位制定主版本 WSAEnumProtocols(); 查询协议信息 ,失败返回错误信息 SOCKET socket( );成功返回套接字,失败返回 INVALID_SOCKET int bing( SOCKET s, const struct sockaddr FAR *name, int namelen ); 失败返回 SOCKET_ERROR 错误,使用 TCP/IP 时返回 WSAEADDRINUSE 错误表示端口已经被用或处于 TIME_WAIT 状态,如果绑定一个已经绑定的套接字将返回 WASEFAULT ,错误返回 -,常见错误信息是 WSAEINVAL 表示在监听之前未调用 bind SOCKET accept( SOCKET s, struct sockaddr *addr, int *addrlen ); s 是出于监听状态的描述字;addr 是一个有效的地址,在 accpt 返回后包含客户机的 IP 地址信息;addrlen 是 addr 的长度;成功返回新的套接字 , WSAECONREFUSED 表示要连接的计算机没有监听指定端口的这一进程,WSAETIMEOUT 表示连接超时 表示无特殊行为,MSG_DONTROUTE 表示要求传输层不要把它发出的数据报路由出去,MSG_OOB 表示数据应该被带外发送;成功返回发送的字节数,错误返回 -,错误信息为 WSAECONNABORTED 表示虚拟回路由于超时或协议有错而中断时,WSAECONNRESET 表示远程主机套接字被强行或意外关闭,WSAETIMEOUT 表示由于网络故障或远程主机系统异常而引起连接中断;成功调用 send 并不意味着数据传输成功,如传送系统的缓冲区空间不够,除非套接字出于非阻塞 I/O 方式,否则 send 函数被阻塞 表示无特殊行为,为 MSG_PEEK 表示将有用数据复制到所需缓冲区后不从系统缓冲区删除它们 int shutdown( SOCKET s, int how ); 中断连接,防止丢失数据,发送端通知接收端不再发送数据或接收端通知发送端不再接受数据;无论如何 shutdown 函数都不会阻塞;how 为 SD_RECEIVE 表示不再接收数据,SD_SEND 表示不再发送数据,SD_BOTH 不再接收和发送 int closesocket( SOCKET s ); 关闭套接字;调用关闭了的套接字会出现 WSAENOTSOCK 错误 int recvfrom( SOCKET s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen ); 当函数返回时 from 中填入发送数据端的地址 int sendto( SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen ); to 带有接收数据的套接字目标地址信息 unsigned 位无符号长整型,同时取 IP 地址为 INADDR_ANY 以允许服务器应用监听主机上每个网络接口上的客户端活动 char *inet_ntoa( struct in_addr in ); 将 in_addr 结构转换到点分十进制 IP u_short htons( u_short hostshort ); u_long ntohs( u_long netlong ); ,失败返回 - struct hostent *gethostbyname( const char *name ); name 是指向主机名的指针,可由 gethostname 得到 struct hostent *gethostbyaddr( const char *addr ); ;设置为非阻塞模式后 WinSock API 会立刻返回,这些调用在大多数情况下会失败,返回 WSAEWOULDBLOCK 信息表示请求的操作在调用期间没有时间完成 int getsocketopt( SOCKET s, int level, int optname, char *optval, int *optlen ); IO 复用 int select( int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout ); nfds 用来对齐,可以忽略;WinSock 提供了 FD_SETSIZE 变量确定集合中最多的套接字描述字数目,可用 #define 自定义;成功返回 0,失败返回 -1 FD_CLR( s, *set ); 从集合中删除描述字 FD_ISSET( s, *,否则返回 FD_SET( s, *set ); 向集合中添加 s FD_ZERO( *set ); 将 set 初始化为空集 NULL int WSAAsycSelect( SOCKET s, HWND hwnd, unsigned int wMsg, long lEvent ); 将网络事件产生的消息发送给应用程序窗口句柄 注册表操作 LONG RegopenKeyEX( HKEY hkey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult ); 打开一个指定的注册表键;hkey 作为输入参数,可取值 HKEY_CLASS_ROOT, HKEY_CURRENT_CONFIG, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_PERFORMANCE_DATA( NT ), HKEY_DYN_DATA( 9x );lpSubKey 作为输入参数指向一个非中断字符串包含将要打开键的名称,字符串以 值 LONG RegCloseKey( HKEY hkey ); 释放制定注册键的句柄;成功返回 ERROR_SUCCESS,失败返回非 值 LONG RegCreateKeyEx( HKEY hkey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition ); 打开一个注册表键值,键存在时打开它,不存在则创建;Reserved 必须设置为 ;lpClass 是一个字符串指针,指定键的类型,常为 NULL;dwOptions 指定键的特殊选项;lpSecurityAttributes 是一个指针,指定访问的安全特性;lpdwDisposition 指明参数是被创建还是被打开,REG_CREATE_NEW_KEY 表示创建,REG_OPEND_EXISTING_KEY 表示打开;成功返回 ERROR_SUCCESS, 失败返回非 LONG RegDeleteKey( HKEY hKey, LPCTSTR lpSubKey ); 删除一个注册表键值,删除的键值必须要有访问权限;lpSubKey 是删除的子键,但它不能有子键,他不能为空,键值不区分大小写;成功返回 ,失败返回非 LONG RegQueryValueEx( HKEY hKey, LPCTSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData ); 获取指定键的数据和类型;lpValueName 是指要获取数据名字;lpType 用于装载取回数据的类型;lpData 是用于装载指定值的缓冲区;lpcbData 是用于装载 lpData 缓冲区长度,返回成功时设为实际装载的长度 RegEnumKeyEx 网络基本应用 UCHAR NetBIOS( PNCB pNCB ); IP 配置信息管理 DWORD GetNetworkParams( PFIXED_INFO pFixedInfo, PULONG pOutBufLen ); 获取本地计算机网络参数;pFixedInfo 参数用来返回本地计算机的网络参数; pOutBufLen 作为输入时指定 pFixedInfo 缓冲区大小,作为输出时如果提供的缓冲区不够函数返回需要缓冲区大小;成功返回 ERROR_SUCCESS DWORD GetNumberOfInterfaces( PDWORD pdwNumIf ); 返回本地计算机网络接口的数量; pdwNumIf 获取数量;成功返回 NO_ERROR DWORD GetInterfaceInfo( PIP_INTERFACE_INFO pIfTable, PULONG dwOutBufLen ); 返回本地计算机上网络接口适配器列表; pIfTable 返回适配器列表,如果 pfIftable 为 NULL 或空,则 dwOutBufLen 返回所需缓冲区大小;成功返回 NO_ERROR;失败返回 ERROR_INSUFFICIENT_BUFFER 表示缓冲区大小不够,需重新分配 DWORD GetIfEntry( PMIB_IFROM pIfRow ); 返回一个包含特定适配器信息的 MIB_IFROW 结构 DWORD SetIfEntry( PMIB_IFROM pIfRow ); DWORD GetIfTable( PMIB_IFTABLE pIfTable, PULONG pdwSize, BOOL bOrder ); 获取整个 MIB_IF 接口表的信息;pdwSize 作为输入时指定 pIfTable 缓冲区大小;作为输入时若提供的缓冲区不足,则返回所需缓冲区大小;bOrder 指定返回的接口表中的入口是否按照接口索引升序排列 DWORD GetIpAddrTable( PMIB_IPADDRTABLE pIpAddrTable, PULONG pdwSize, BOOL bOrder ); 取得一张包含了 IP 地址到接口的映射表; pdwSize 输入时指定 pIpAddrTable 缓冲区大小,输出时表示缓冲区不足,返回所需缓冲区大小; DWORD AddIPAddress( IPADDR Address, IPMask IpMask, DWORD IfIndex, PULONG NTEContext, PULONG NTEInstance ); 向特定接口添加临时 IP 地址;IfIndex 是适配器索引;NTEContext 网络表入口;NTEInstance 网络表实例 DWORD DeleteIPAddress( ULONG NTEContext ); 删除 IP 地址 BOOL DhcpNotifyConfigChange( LPWSTR lpwszServerName, LPWSTR lpwszAdapterName, BOOL bNewIpAddress, DWORD dwIpIndex, DWORD dwIpAddress, DWORD dwSubNetMask, 不修改, 启动 DHCP , 禁用 DHCP 辅助函数 ); 获得 IP 地址,是网络字节序,lpAddr 等于 hostent.h_addr_list[];调用 .isEmpty() 方法可以判断是否得到 IP 地址 , HGLOBAL GlobalAlloc( UINT uFlags, DWORDdwBytes ); 全局堆分配,提供这个函数只是为了与 位的 Windows 相兼容;分配属性(方式),GMEM_ZEROINIT 申请内存初始化为 , GMEM_MOVEABLE 分配可移动内存,返回指针, GMEM_FIXED分配固定内存,返回指针, GPTR 固定和初始化, GHND 移动和初始化,分配的字节数;成功返回句柄,失败返回 NULL GlobalFree char *LoadLibrary( char * ); 加载库文件;成功返回指向库文件名的指针 library_point,失败返回 NULL char *FreeLibrary( char * ); char *GetProcAddress( library_point, function_name ); 成功返回函数的别名,可通过别名调用函数 strlen_s char *strrev( char *s ); 字符串反转,不包括 NULL, Linux系统中没有 __strrev 函数 itoa int atoi( const char *nptr ); 字符串转化为整数 头文件 conio.h IPHlpApi.h IP 助手 nb30.h Winbase.h 包含在 windows.h 中 WinDef.h 类型定义 Windows.h WinNT.h WCHAR, CHAR, CCHAR WinSock1.h WinSock2.h WSAPROTOCOL_INFO wtypes.h 库文件 #pragma comment( lib, "netapi32.lib"); iphlpapi.lib IP 助手 Kernel32.lib. GlobalAlloc netapi32.lib NCB ws2_32.lib WinSock2 自定义类型 BOOL typedef int BOOL; BOOLEAN typedef BYTE BOOLEAN; BYTE typedef unsigned char BYTE; CCHAR typedef char CCHAR; CHAR typedef char CHAR;系统移植 CONST #define CONST const DWORD typedef unsigned -bit unsigned integer INT typedef int INT; 32bits INT8 typedef signed char INT8; INT16 typedef signed short INT16; INT32 typedef signed int INT32; INT64 typedef signed __int64 INT64; LONG typedef -bit signed integer LONGLONG #if !defined(_M_IX86) typedef __int64 LONGLONG; #else typedef double LONGLONG; #endif(C++) PVOID typedef void *PVOID; TCHAR #ifdef UNICODE typedef WCHAR TCHAR; #else typedef char TCHAR; #endif UCAHR typedef unsigned char UCHAR; WCHAR typedef wchar_t WCHAR; -bit Unicode character WORD typedef unsigned short WORD; fd_set HANDLE typedef PVOID HANDLE; HGLOBAL typedef HANDLE HGLOBAL; HKEY typedef HANDLE HKEY; LANA_ENUM 该结构中包含系统中逻辑网卡数目及每个网卡号;LANA 编号对应于网卡及传输协议的唯一组合 LPCTSTR PHKEY PIP_ADAPTER_INFO REGSAM https://msdn.microsoft.com/en-us/library/aa383751 结构体 typedef struct WSAData{ WORD wVersion; //希望使用的 Winsock 版本, WORD wHighVersion; //返回现有 WinSock 库的最高版本 ]; //长度不能超过 256,通常不使用 ]; //长度不能超过 256,通常不使用 unsigned short iMaxSockets; //可同时打开的套接字数,不固定,一般不使用 unsigned short iMaxUdpDg; //数据报最大长度,一般不使用,用 WSAEnumProtocols 查询 char FAR *lpVendorInfo; //不使用 char FAR *LPWSADATA; }WASDATA, *LPWSADATA; struct sockaddr{ u_short sa_family; ]; }; struct sockaddr_in{ short sin_family; //必须设为 AF_INET u_short sin_port; //要把端口号由主机字节序转换为网络字节序,设置为 0 则由应用程序分配一个 1024~5000 之间的一个端口 struct in_addr sin_addr; //存放 4 位字节无符号长整型的 IP 地址 ]; //填充项 } typedef struct in_addr { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; } IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR; typedef struct { union { struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; struct { u_short s_w1,s_w2; } S_un_w; u_long S_addr; } S_un; } IPAddr; struct timeval{ long tv_sec; long tv_usec; //毫秒 } struct hostent{ char *h_name; char *h_aliases; short h_addrtype; // 一般为 AF_INET short h_length; // 一般为 4 char *h_addr_list; // 存放 ip 地址列表的数组,每个元素存放一个 IP 地址 } typedef struct _NCB{ // 网络控制块 UCHAR ncb_command; NetBIOS 执行的命令 UCHAR ncb_retcode; 操作的返回代码 UCHAR ncb_lsn; 对应本地会话编号 UCHAR ncb_num; 指定本地会话编号 PUCHAR ncb_buffer; 数据缓冲区 WORD ncb_length; 缓冲区长度 UCHAR ncb_callname[NCBNAMSZ]; 指定远程应用的名字 UCHAR ncb_name[NCBNAMSZ]; 指定应用程序已知的名字 UCHAR ncb_rto; 接受操作的时限 UCHAR ncb_sto; 发送操作的时限 void( CALLBACK *ncb_post )( struct _NCB *); 制定异步命令完成后需要调用的后例程的地址 UCHAR ncb_lana_num; 指定上面执行命令的 LANA 编号 UCHAR ncb_cmd_cplt; 指定操作的返回代码 #ifdef _WIN64 UCHAR ncb_reserve[]; 保留字段 #else UCHAR ncb_reserve[]; #endif HANDLE ncb_event; 设置为“未传信”状态 }NCB, *PNCB; typedef struct _WSAPROTOCOL_INFO { DWORD dwServiceFlags1; 表示不同协议属性的一个位字段;XP1_CONNECTIONLESS(0x00000001),XP1_GUARANTEED_DELIVERY,XP1_GUARANTEED_ORDER,XP1_MESSAGE_ORIENTED,XP1_PSEUDO_STREAM,XP1_GRACEFUL_CLOSE,XP1_EXPEDITED_DATA,XP1_CONNECT_DATA,XP1_DISCONNECT_DATA,XP1_SUPPORT_BROADCAST,XP1_SUPPORT_MULTIPOINT,XP1_MULTIPOINT_CONTROL_PLANE,XP1_MULTIPOINT_DATA_PLANE,XP1_QOS_SUPPORTED,XP1_INTERRUPT,XP1_UNI_SEND,XP1_UNI_RECV,XP1_IFS_HANDLES,XP1_PARTIAL_MESSAGE,XP1_SAN_SUPPORT_SDP DWORD dwServiceFlags2; Reserved for additional protocol-attribute definitions. DWORD dwServiceFlags3; Reserved for additional protocol-attribute definitions. DWORD dwServiceFlags4; Reserved for additional protocol-attribute definitions. DWORD dwProviderFlags; GUID ProviderId; 协议提供商 DWORD dwCatalogEntryId; A unique identifier assigned by the WS2_32.DLL for each WSAPROTOCOL_INFO structure WSAPROTOCOLCHAIN ProtocolChain; 协议链 int iVersion; The protocol version identifier. int iAddressFamily; 地址簇;区分正确协议的定义结构;AF_INET,AF_IPX,AF_APPLETALK,AF_NETBIOS,AF_INET6,AF_IRDA,AF_BTH int iMaxSockAddr; The maximum address length, in bytes. int iMinSockAddr; The minimum address length, in bytes. int iSocketType; 定义套接字类型;SOCK_STREAM,SOCK_DGRAM,SOCK_RAW,SOCK_RDM,SOCK_SEQPACKET int iProtocol; 定义该条目属于哪一个协议;IPPROTO_ICMP,IPPROTO_IGMP,BTHPROTO_RFCOMM,IPPROTO_TCP,IPPROTO_UDP,IPPROTO_ICMPV6,IPPROTO_RM int iProtocolMaxOffset; and int iSecurityScheme; 支持的安全特性 DWORD dwMessageSize; The maximum message size, in bytes, supported by the protocol; DWORD dwProviderReserved; Reserved for use by service providers TCHAR szProtocol[WSAPROTOCOL_LEN+]; contains a human-readable name identifying the protocol } WSAPROTOCOL_INFO, *LPWSAPROTOCOL_INFO; https://msdn.microsoft.com/en-us/library/windows/desktop/ms741675(v=vs.85).aspx typedef struct{ ]; ]; PIP_ADDR_STRING CurrentDnsServer; IP_ADDR_STRING DnsServerList; UINT NodeType; ]; UINT EnableRouting; UINT EnableProxy; UINT EnableDns; }FIXED_INFO, *PFIXED_INFO; typedef struct _IP_ADDR_STRING{ struct _IP_ADDR_STRING *Next; IP_ADDRESS_STRING IpAddress; //该结构体中包含字符串成员 String,描述了点分十进制 ip 地址 IP_MASK_STRING IpMask; DWORD Context; //表示网络表入口 }IP_ADDR_STRING, *PIP_ADDR_STRING; typedef struct _IP_INTERFACE_INFO{ LONG NumAdapters; //指示 Adapter 数组中适配器数量 IP_ADAPTER_INDEX_MAP Adapter[]; // }IP_INTERFACE_INFO, *PIP_INTERFACE_INFO; typedef struct _IP_ADAPTER_INDEX_MAP{ ULONG index; //与此适配器关联的接口索引 WCHAR Name[MAX_ADAPTER_INDEX_MAP]; //适配器名称 }IP_ADAPTER_INDEX_MAP, *PIP_ADAPTER_INDEX_MAP; typedef struct _MIB_IFTABLE{ DWORD dwNumEntries; //指定数组中入口的数量 MIB_IFROW table[ANY_SIZE]; //指定接口表 }MIB_IFTABLE, *PMIB_IFTABLE; typedef struct _MIB_IFROW{ WCHAR wszName[MAX_INTERFACE_NAME_LEN]; //指定接口名称 DWORD dwIndex; //指定标识接口的索引 DWORD dwType; //指定接口类型 MIB_IF_TYPE_ETHERNET MIB_IF_TYPE_PPP DWORD dwMtu; //指定最大传输单元 DWORD dwSpeed; //接口速度 DWORD dwPhysAddrLen; // bPhysAddr 所指物理地址长度 BYTE bPhysAddr[MAXLEN_PHYSADDR]; // DWORD dwAdminStatus; //接口管理状态,MIB_IF_ADMIN_STATUS_UP/DOWN 接口(不)可被管理 DWORD dwOperStatus; //接口运行状态 DWORD dwLastChange; // DWORD dwInOctets; //此接口接收到的八进制数据数量 DWORD dwInUcastPkts; //此接口收到的单播封包数量 DWORD dwInNucastPkts; //非单播封包 DWORD dwInDiscards; //已经丢弃的封包数量(不出错的) DWORD dwInErrors; //丢弃的出错的封包数量 DWORD dwInUnknownProtos; // DWORD dwOutOctets; // DWORD dwOutUcastPkts; // DWORD dwOutNUcastPkts; // DWORD dwOutDiscards; // DWORD dwOutErrors; // DWORD dwOutQlen; //发送队列长度 DWORD dwDescrLen; //指定 bDescr 长度 BYTE bDescr[MAXLEN_IFDESCR]; //接口描述信息 }MIB_IFROW, *PMIB_IFROW; typedef struct _MIB_IPADDRTABLE{ DWORD dwNumEntries; MIB_IPADDRROW table[ANY_SIZE]; }MIB_IPADDRTABLE, *PMIB_IPADDRTABLE; typedef struct _MIB_IPADDRROW{ DWORD dwAddr; //指示 IP 地址 DWORD dwIndex; //指示与 IP 地址关联的接口索引 DWORD dwMask; //子网掩码 DWORD dwBCastAddr; //广播地址 DWORD dwReasmSize; //对已收到的数据报进行重新组装后的最大长度 unsigned short unused1; //保留位 unsigned short wType; //指定地址类型或状态; MIB_IPADDR_PRIMARY 主 IP 地址,DYNAMIC 动态地址,DISCONNECTED 地址在未连接的接口上,DELETE 地址将要被删除,TRANSIENT 瞬时地址 }MIB_IPADDRROW, *PMIB_IPADDRROW; 注册表 基础 unsigned 位。 TCP 服务端模型:socket -> bind -> accept -> recv -> send -> close // 调用 shutdown TCP 客户端模型:socket -> connect -> send -> recv -> close UDP 服务端模型:socket -> bind -> recvfrom -> sendto -> close UDP 客户端模型:socket -> sendto -> recvfrom -> close 利用 netbios 获取网卡号不一定准确,因为他会得到很多虚拟网卡地址。 实例 WSADATA wsaData; WSAStartup( MAKEWORD(,), &wsaData );
最新文章
- ArcGIS制作放射状流向地图(Radial Flow Map)
- Linux学习之二--搭建FTP服务器
- JMS相关概念
- win7-opengl开发环境的搭建
- BZOJ_1833_[ZJOI2010]_数字计数_(数位dp)
- HDOJ 1018 Big Number(大数位数公式)
- js提取整数部分,移除首末空格
- placeholder 兼容 IE
- JavaWeb解释一下什么是 servlet?
- SQL SERVER 索引名前缀代表的意思
- 排序算法的C语言实现(下 线性时间排序:计数排序与基数排序)
- Jmeter性能结果分析
- 020100——00002_OS库
- golang基础学习及web框架
- Visual C++.NET设计
- 微信小程序 - 入门指引
- JavaScript原型之路
- Copycat - MemberShip
- JavaScript对象参考手册
- Base64转码和解码的帮助类