一些网络开发函数
来源:互联网 发布:宝塔性能优化 编辑:程序博客网 时间:2024/05/29 03:19
几个基础结构体
struct sockaddr { unsigned short sa_family; char sa_data[14]; }; struct sockaddr_in { short int sin_family; unsigned short int sin_port; struct in_addr sin_addr; unsigned char sin_zero[8]; };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; #define s_addr S_un.S_addr}; //sockaddr与sockaddr_in之间可以相互转换。in_addr存放的是网络字节序的32位无符号整型IP地址。
几个小端和网络字节序之间的转换函数
//小端转网络字节序u_long htonl(u_long hostlong);u_short htons(u_short hostshort);//网络字节序转小端u_long ntohl(u_long netlong);u_short ntohs(u_long netshort);//其实上面的函数,像htonl也可以用于网络字节序转小端,但为了代码便于阅读,还是养成习惯吧。
//字符串点分十进制 和 网络字节序32位无符号整型 的IP地址的转换函数//旧函数unsigned long inet_addr( _In_ const char *cp);char* FAR inet_ntoa(//返回的字符串如果要操作最好拷贝到自己的内存中 _In_ struct in_addr in);//新函数,支持IPv4、IPv6INT WSAAPI InetPton( _In_ INT Family, _In_ PCTSTR pszAddrString, _Out_ PVOID pAddrBuf //in_addr或unsigned long变量的指针);PCTSTR WSAAPI InetNtop( _In_ INT Family, _In_ PVOID pAddr, //in_addr或unsigned long变量的指针 _Out_ PTSTR pStringBuf, _In_ size_t StringBufSize);
几个名字解析函数
//IP地址和主机名之间的转换函数//旧函数struct hostent* FAR gethostbyname( _In_ const char *name);/*gethostbyname中操作h_addr_list hostent *test = gethostbyname("主机名"); char ret[256]; inet_ntop(AF_INET, *++(test->h_addr_list), rer, 256); MessageBox((rer));*/struct hostent* FAR gethostbyaddr( _In_ const char *addr, _In_ int len, _In_ int type);//hostent结构体,返回的hostent由系统管理,不用自己释放typedef struct hostent { char FAR *h_name; char FAR FAR **h_aliases; short h_addrtype; short h_length; char FAR FAR **h_addr_list;//按网络字节序存储的,要注意} HOSTENT, *PHOSTENT, FAR *LPHOSTENT;//新函数,WS2tcpip.h中int WSAAPI getaddrinfo( _In_opt_ PCSTR pNodeName, _In_opt_ PCSTR pServiceName, _In_opt_ const ADDRINFOA *pHints, _Out_ PADDRINFOA *ppResult);int WSAAPI getnameinfo( _In_ const struct sockaddr FAR *sa, _In_ socklen_t salen, _Out_ char FAR *host, _In_ DWORD hostlen,//NI_MAXHOST _Out_ char FAR *serv, _In_ DWORD servlen,//NI_MAXSERV _In_ int flags //flags有NI_NUMERICSERV、NI_NOFQDN、NI_NUMERICHOST、NI_NAMEREQD、NI_DGRAM);#define NI_MAXSERV 32#define NI_MAXHOST 1025//getaddrinfo和getnameinfo执行成功返回0,执行失败返回非0//获取错误代码比较特别,不是用WSAGetLastError()//而是调用gai_strerror(返回代码)获得错误信息字符串。但官方文档说这个函数是非线程安全的,所以对于各错误代码官网有说明,看需要吧。char* gai_strerror( _In_ int ecode);//getaddrinfo中的ADDRINFOA声明如下,调用getaddrinfo后返回的ppResult,要调用freeaddrinfo(*ppResult)释放该结构提typedef struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo *ai_next;} ADDRINFOA, *PADDRINFOA;//释放addrinfo结构体空间void freeaddrinfo( _In_ struct addrinfo *ai);
提一下getaddrinfo函数调用时参数的填充。
在getaddrinfo函数之前通常需要对以下6个参数进行以下设置:nodename、servname、hints的ai_flags、ai_family、ai_socktype、ai_protocol。
在6项参数中,对函数影响最大的是nodename,sername和 h i n t s . ai_flag,而ai_family只是有地址为v4地址或v6地址的区别。ai_protocol一般是为0不作改动。
getaddrinfo在实际使用中的几种常用参数设置:
addrinfo hint,*result; ZeroMemory(&hint, sizeof(addrinfo)); hint.ai_flags = AI_PASSIVE; //AI_PASSIVE+空主机+非空端口=通配地址 //无AI_PASSIVE+空主机+非空端口=环回地址 //无论有无AI_PASSIVE+非空主机+无论有无端口=所有地址 hint.ai_family = AF_INET; hint.ai_protocol = IPPROTO_IP; int ret = getaddrinfo("主机名", NULL , &hint, &result); if (ret != 0) { MessageBox(gai_strerror(ret)); } //。。。操作 freeaddrinfo(result);
几个信息获取函数
//获取主机上支持的协议和协议特性int WSAEnumProtocols( _In_ LPINT lpiProtocols, _Out_ LPWSAPROTOCOL_INFO lpProtocolBuffer, _Inout_ LPDWORD lpdwBufferLength);//获取协议的状态信息DWORD GetTcpStatistics( _Out_ PMIB_TCPSTATS pStats);DWORD GetUdpStatistics( _Out_ PMIB_UDPSTATS pStats);DWORD GetIpStatistics( _Out_ PMIB_IPSTATS pStats);DWORD GetIcmpStatistics( _Out_ PMIB_ICMP pStats);//获取活动的TCP或UDPDWORD WINAPI GetTcpTable( _Out_ PMIB_TCPTABLE pTcpTable, _Inout_ PDWORD pdwSize, _In_ BOOL bOrder);DWORD GetUdpTable( _Out_ PMIB_UDPTABLE pUdpTable, _Inout_ PDWORD pdwSize, _In_ BOOL bOrder);//可以获取本地接口的所有IP地址DWORD GetIpAddrTable( _Out_ PMIB_IPADDRTABLE pIpAddrTable, _Inout_ PULONG pdwSize, _In_ BOOL bOrder);//获取网络适配器信息DWORD GetAdaptersInfo( _Out_ PIP_ADAPTER_INFO pAdapterInfo, _Inout_ PULONG pOutBufLen);
其他函数
setsockopt:https://msdn.microsoft.com/en-us/library/windows/desktop/ms740476(v=vs.85).aspx
WSAIoctl:https://msdn.microsoft.com/en-us/library/windows/desktop/ms741621(v=vs.85).aspx
int setsockopt( _In_ SOCKET s, _In_ int level, _In_ int optname, _In_ const char *optval, _In_ int optlen);int WSAIoctl( _In_ SOCKET s, _In_ DWORD dwIoControlCode, _In_ LPVOID lpvInBuffer, _In_ DWORD cbInBuffer, _Out_ LPVOID lpvOutBuffer, _In_ DWORD cbOutBuffer, _Out_ LPDWORD lpcbBytesReturned, _In_ LPWSAOVERLAPPED lpOverlapped, _In_ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
SIO_RCVALL:https://msdn.microsoft.com/en-us/library/windows/desktop/ee309610(v=vs.85).aspx
在网络开发过程中还有很多API函数,这只是最近学习到的,整理一波吧。
顺带一提,MFC中ip地址控件的GetAddress方法返回的是小端的32位u_long.
文末贴一下各数据包结构,很有用。
数据包结构体摘自:http://www.cnblogs.com/RodYang/p/3271878.html
//以太帧头格式结构体,共14个字节: typedef struct ether_header { unsigned char ether_dhost[6]; //目的MAC地址 unsigned char ether_shost[6]; //源MAC地址 unsigned short ether_type; //协议类型 }ETHHEADER,*PETHHEADER;//IPv4报头格式结构体,共20个字节: typedef struct ipv4_header {unsigned char ver_ihl; //版本 (4 bits) + 首部长度 (4 bits)unsigned char tos; //服务类型unsigned short tlen; //数据报总长度unsigned short identification; //标识unsigned short flags_fo; //标志 (3 bits) + 片偏移 (13 bits) unsigned char ttl; //生存时间unsigned char proto; //协议unsigned short crc; //首部校验和u_char ip_src[4]; //源IP地址u_char ip_dst[4]; //目的IP地址 }IPHEADER,*PIPHEADER;//IPv6报头格式结构体,共40个字节:typedef struct ipv6_header {u_char ver_tf; //版本号(4 bit)u_char traffic; //优先级(8 bit)u_short label; //流标识(20 bit)u_char length[2]; //报文长度(16 bit)u_char next_header; //下一头部(8 bit)u_char limits; //跳数限制(8 bit)u_char Srcv6[16]; //源IPv6地址(128 bit)u_char Destv6[16]; //目的IPv6地址(128 bit)}IPv6_HEADER,*PIPv6_HEADER;//TCP报头格式结构体,共20个字节:typedef struct tcp_header {WORD SourPort; //源端口号 WORD DestPort; //目的端口号DWORD SeqNo; //序号DWORD AckNo; //确认序号BYTE HLen; //首部长度(保留位)BYTE Flag; //标识(保留位)WORD Window; //窗口大小WORD ChkSum; //校验和WORD UrgPtr; //紧急指针}TCPHEADER,*PTCPHEADER;//UDP报头格式结构体,共8个字节:typedef struct udp_header {u_short sport; //源端口号u_short dport; //目的端口号u_short len; //数据报长度u_short crc; //校验和}UDPHEADER,*PUDPHEADER;
- 一些网络开发函数
- 网络编程的一些函数
- 网络开发的一些总结
- 网络开发的一些总结
- [ios开发] 一些小函数
- 一些网络编程中api函数
- java 网络编程的一些函数
- 网络编程中常用的一些函数
- 网络编程中一些小函数
- socket网络编程的一些基本函数
- 网络开发时用到的一些库
- 摘抄一些关于网络开发的帖子
- 开发中需要的一些网络判断
- 开发中经常用到的一些函数
- asp.net常见开发的一些函数
- [转] WINCE 下 开发的 一些函数
- 学习笔记 android开发 一些函数记录
- Android相机开发中的一些函数
- android自定义view的两种方法(一)
- vim编辑器的简单操作
- ubuntu的文字解决方案
- Android 自定义Drawable 实现圆角圆形图片
- 装机那些事
- 一些网络开发函数
- 形态学处理:膨胀、腐蚀、开运算、闭运算、形态学梯度、顶帽、黑帽
- 网易云音乐一件换曲插件
- android拒绝token过期的一种方法
- opencv读取海康威视摄像头
- Java经典算法(三)
- hdu 5933 ArcSoft's Office Rearrangement
- 第几天
- 三.Contiki之etimer定时器(1)——etimer定义与产生