网络字节序
来源:互联网 发布:win10仿mac桌面dock 编辑:程序博客网 时间:2024/06/05 10:04
大端模式:从高字节开始存储;小端模式:从低字节开始存储;
点分十进制(presentation)和网络地址结构的二进制格式(numeric)使用 inet_pton , inet_ntop.
对于上面的调用必须确定是IPv4或IPv6的地址(&addr6.sin6_addr)可以利用包裹函数,通用处理(sock_ntop):
网络协议必须协调一致字节序(网络字节序),同时也要考虑到不同主机的实际情况,所以存在二者之间的转换。
常见的函数有 htons,htonl,ntohs,ntohl。
查看主机字节序(UNPv1 P64):
#include<stdio.h>#include<stdlib.h>intmain(int argc, char **argv){ union { short s; char c[sizeof(short)]; } un;//?? un.s = 0x0102; if (sizeof(short) == 2) { if (un.c[0] == 1 && un.c[1] == 2) printf("big-endian\n"); else if (un.c[0] == 2 && un.c[1] == 1) printf("little-endian\n"); else printf("unknown\n"); } else printf("sizeof(short) = %ld\n", sizeof(short)); exit(0);}
点分十进制(presentation)和网络地址结构的二进制格式(numeric)使用 inet_pton , inet_ntop.
#include<arpa/inet.h>
int inet_pton(int family, const char *str, void *addrptr);
const char *inet_ntop(int family, const void *addptr,char *str,size_t len); 注意第二个参数;
简单实现上述功能(IPv4):
#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <errno.h>#include <string.h>intmy_inet_pton(int family, const char *strptr, void *addrptr){ if (family == AF_INET) { struct in_addr in_val; if (inet_aton(strptr, &in_val)) { memcpy(addrptr, &in_val, sizeof(struct in_addr));intmy_inet_pton(int family, const char *strptr, void *addrptr){ if (family == AF_INET) { struct in_addr in_val; if (inet_aton(strptr, &in_val)) { memcpy(addrptr, &in_val, sizeof(struct in_addr)); return (1); } return(0); } errno = EAFNOSUPPORT; return (-1);}const char *my_inet_ntop(int family, const void *addrptr, char *strptr, size_t len){ const u_char *p = (const u_char *) addrptr; if (family == AF_INET) { char temp[INET_ADDRSTRLEN]; snprintf(temp, sizeof(temp), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); if (strlen(temp) >= len) { errno = ENOSPC; return (NULL); } strcpy(strptr, temp); return (strptr); } errno = EAFNOSUPPORT; return (NULL);}int main(){ char buf[INET_ADDRSTRLEN]={0}; struct sockaddr_in addr; addr.sin_family=AF_INET; addr.sin_addr.s_addr = inet_addr("192.168.4.135"); printf("%s\n",my_inet_ntop(AF_INET,(const void *)&addr.sin_addr,buf,sizeof(buf)));// printf("%s\n",inet_ntop(AF_INET,(const void *)&addr.sin_addr,buf,sizeof(buf))); return 0;}
对于上面的调用必须确定是IPv4或IPv6的地址(&addr6.sin6_addr)可以利用包裹函数,通用处理(sock_ntop):
#include "util.h"#ifdef HAVE_SOCKADDR_DL_STRUCT#include <net/if_dl.h>#endif/* include sock_ntop */char *sock_ntop(const struct sockaddr *sa, socklen_t salen){ char portstr[8]; static char str[128]; /* Unix domain is largest */ switch (sa->sa_family) { case AF_INET: { struct sockaddr_in *sin = (struct sockaddr_in *) sa; if (inet_ntop(AF_INET, &sin->sin_addr, str, sizeof(str)) == NULL) return(NULL); if (ntohs(sin->sin_port) != 0) { snprintf(portstr, sizeof(portstr), ":%d", ntohs(sin->sin_port)); strcat(str, portstr); } return(str); }/* end sock_ntop */#ifdef IPV6 case AF_INET6: { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; str[0] = '['; if (inet_ntop(AF_INET6, &sin6->sin6_addr, str + 1, sizeof(str) - 1) == NULL) return(NULL); if (ntohs(sin6->sin6_port) != 0) { snprintf(portstr, sizeof(portstr), "]:%d", ntohs(sin6->sin6_port)); strcat(str, portstr); return(str); } return (str + 1); }#endif#ifdef AF_UNIX case AF_UNIX: { struct sockaddr_un *unp = (struct sockaddr_un *) sa; /* OK to have no pathname bound to the socket: happens on every connect() unless client calls bind() first. */ if (unp->sun_path[0] == 0) strcpy(str, "(no pathname bound)"); else snprintf(str, sizeof(str), "%s", unp->sun_path); return(str); }#endif#ifdef HAVE_SOCKADDR_DL_STRUCT case AF_LINK: { struct sockaddr_dl *sdl = (struct sockaddr_dl *) sa; if (sdl->sdl_nlen > 0) snprintf(str, sizeof(str), "%*s (index %d)", sdl->sdl_nlen, &sdl->sdl_data[0], sdl->sdl_index); else snprintf(str, sizeof(str), "AF_LINK, index=%d", sdl->sdl_index); return(str); }#endif default: snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d", sa->sa_family, salen); return(str); } return (NULL);}char *Sock_ntop(const struct sockaddr *sa, socklen_t salen){ char *ptr; if ( (ptr = sock_ntop(sa, salen)) == NULL) perror("sock_ntop error"); /* inet_ntop() sets errno */ return(ptr);}
测试:
#include "util.h"int main(){ struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr("192.168.4.135"); addr.sin_port = htons(13); printf("%s\n",Sock_ntop((const struct sockaddr *)&addr,sizeof(addr))); return 0;}
0 0
- 关于网络字节序
- 网络数据包字节序
- 网络字节序
- 网络字节序
- 网络字节序
- 网络字节序
- 网络字节序
- 网络字节序
- 网络字节序
- 网络字节序转换
- 浅析网络字节序
- 网络字节序
- 网络字节序
- 网络字节序
- 网络字节序
- 网络字节序
- 网络字节序问题
- linux 网络字节序
- TOJ 4453
- Eclipse如何导入jar包(referenced libraries)
- Matlab判断3个数是否互质
- Android中的事件分发机制
- 通过ATL COM组件实现在RichEdit中各种图片的显示(包括Gif图片的显示)
- 网络字节序
- HDU 3537 Daizhenyang's Coin 翻硬币博弈
- socket
- vimperator部分使用帮助
- 拟牛顿法、DFP算法及BFGS算法
- [unity3d]easytouch的使用
- mysql安全篇
- Python之isinstance
- 求解:栈的应用 深度优先搜索:迷宫问题