iOS and OS X Network Programming Cookbook |Performing a network address resolution
2015-06-30 20:23
609 查看
这个部分解决的是host/service name 和 sockadd structure相互转换的问题。
用到的两个方法:
Getaddrinfo():通过给定的host/service name返回相关信息,存储在addrinfo structure中.
Getnameinfo():使用给定的sockaddr structure得到host/service name。
主要步骤(BSD版本):
1.创建一个AddrInfo类,继承自NSObject
这其中定义的第一个方法将会使用getaddrinfo()方法得到results,第二个方法使用getnameinfo()得到hostname和serviece。
2.实现AddInfo类
getaddrinfo()中需要的hostname和service的格式是char array格式,所以要进行转换。如果成功的话errorcode = 0
在results设置新值前释放旧值
3.main函数中的调用
CFNetwork的方法感觉更加复杂,真是找虐啊
主要步骤(CFNetwork部分)
Hostname转换为IP地址
1.使用给定的hostname,利用CFHostCresteWithName创建CFHostRef
2.使用CFHostStartInfoResolution对hostRef进行分解
3.使用CFHostGetAddress取得地址(返回值是数组CFArrayRef),CFArrayGetCount取得地址数组的个数
4.然后使用CFDataGetBytePtr将地址数组中每个数返回为sockaddr struct,再利用getnameinfo()得到ipaddr
Address返回Hostname
1.给定的address,使用getaddrinfo返回addrinfo struct --results
2.使用results中的ai_addr 和 ai_addrlen, 以及CFDataCreate返回CFDataRef
3.CFHostCresteWithAddress创建CFHostRef
4.分解
5.CFHostNames取得名字
6.这个名字数组直接能用
用到的两个方法:
Getaddrinfo():通过给定的host/service name返回相关信息,存储在addrinfo structure中.
Getnameinfo():使用给定的sockaddr structure得到host/service name。
主要步骤(BSD版本):
1.创建一个AddrInfo类,继承自NSObject
#import <netdb.h> #import <netinet/in.h> #import <netinet6/in6.h>
@property (nonatomic, strong) NSString *hostname, *service; @property (nonatomic) struct addrinfo *results; @property (nonatomic) struct sockaddr *sa; @property (nonatomic, readonly) int errorCode; -(void)addrWithHostname:(NSString*)lHostname Service:(NSString *) lService andHints:(struct addrinfo*)lHints; -(void)nameWithSockaddr:(struct sockaddr *)saddr; -(NSString *)errorString;
这其中定义的第一个方法将会使用getaddrinfo()方法得到results,第二个方法使用getnameinfo()得到hostname和serviece。
2.实现AddInfo类
-(void)setVars { self.hostname = @""; self.service = @""; self.results = @""; _errorCode = 0; }
-(void)addrWithHostname:(NSString*)lHostname Service:(NSString *) lService andHints:(struct addrinfo*)lHints { [self setVars]; self.hostname = lHostname; self.service = lService; struct addrinfo *res; _errorCode = getaddrinfo([_hostname UTF8String], [_service UTF8String], lHints, &res); self.results = res; }
getaddrinfo()中需要的hostname和service的格式是char array格式,所以要进行转换。如果成功的话errorcode = 0
-(void)nameWithSockaddr:(struct sockaddr *)saddr { [self setVars]; char host[1024]; char serv[20]; _errorCode = getnameinfo(saddr, sizeof saddr, host, sizeof host, serv, sizeof serv, 0); self.hostname = [NSString stringWithUTF8String:host]; self.service = [NSString stringWithUTF8String:serv]; }代码非常简洁明了,差不多就是上面代码的逆向,成功返回0,不成功返回-1
-(void)setResults:(struct addrinfo *)lResults { abac freeaddrinfo(self.results); _results = lResults; }
在results设置新值前释放旧值
3.main函数中的调用
</pre><pre name="code" class="objc">struct addrinfo *res; struct addrinfo hints; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; AddrInfo *ai = [[AddrInfo alloc] init]; [ai addrWithHostname:@"www.packtpub.com" Service:@"443" andHints:&hints]; struct addrinfo *results = ai.results; for (res = results; res!= NULL; res = res->ai_next) { void *addr; NSString *ipver = @""; char ipstr[INET6_ADDRSTRLEN]; if (res->ai_family == AF_INET) { struct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr; addr = &(ipv4->sin_addr); ipver = @"IPv4"; } else if (res->ai_family == AF_INET6){ struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)res->ai_<pre name="code" class="objc">addr; addr = &(ipv6->sin6_addr); ipver = @"IPv6"; } else { continue; } inet_ntop(res->ai_family, addr, ipstr,sizeof ipstr); NSLog(@" %@ %s", ipver, ipstr); AddrInfo *ai2 = [[AddrInfo alloc] init]; [ai2 getNameWithSockaddr:res->ai_addr]; if (ai2.errorCode ==0) NSLog(@"--%@ %@",ai2.hostname, ai2.service); } freeaddrinfo(results);
CFNetwork的方法感觉更加复杂,真是找虐啊
主要步骤(CFNetwork部分)
Hostname转换为IP地址
1.使用给定的hostname,利用CFHostCresteWithName创建CFHostRef
2.使用CFHostStartInfoResolution对hostRef进行分解
3.使用CFHostGetAddress取得地址(返回值是数组CFArrayRef),CFArrayGetCount取得地址数组的个数
4.然后使用CFDataGetBytePtr将地址数组中每个数返回为sockaddr struct,再利用getnameinfo()得到ipaddr
Address返回Hostname
1.给定的address,使用getaddrinfo返回addrinfo struct --results
2.使用results中的ai_addr 和 ai_addrlen, 以及CFDataCreate返回CFDataRef
3.CFHostCresteWithAddress创建CFHostRef
4.分解
5.CFHostNames取得名字
6.这个名字数组直接能用
相关文章推荐
- java-模拟tomcat服务器
- Linux socket 初步
- C#基于socket模拟http请求的方法
- 简单的Ruby中的Socket编程教程
- Socket不能选择本地IP连接问题如何解决
- C#之Socket操作类实例解析
- C#使用Socket快速判断数据库连接是否正常的方法
- 科学知识:理解socket
- php与flash as3 socket通信传送文件实现代码
- 解决time_wait强制关闭socket
- C#使用Socket上传并保存图片的方法
- 深入php socket的讲解与实例分析
- JavaScript Archive Network 集合
- Linux网络编程之UDP Socket程序示例
- Linux网络编程之socket文件传输示例
- filezilla Failed to create listen socket on port 21 for IPv4 解决办法
- php socket方式提交的post详解
- PHP异步调用socket实现代码
- PHP实现Socket服务器的代码
- udp socket客户端和udp服务端程序示例分享