[疑难] 请教 异步 gethostbyname

hurd 2009-05-03
小弟最近在写个windows控制台程序, 需要用到异步gethostbyname。
windows下有个WSAAsyncGetHostByName,但是必须用窗口线程来接受结果。
请教有什么办法能不用窗口,又不必创建多个线程的解决办法。
zhangyafei_kimi 2009-05-03
boost好像可以,我记得例子里面有。
zhangyafei_kimi 2009-05-03
不好意思,没看清楚这里是D论坛
qiezi 2009-05-04
可以自己解析dns协议。。
hurd 2009-05-05
写个一个阻塞的,调用receiveFrom一直返回-1,哪位有空给看看程序。

import 
	tango.sys.win32.UserGdi,
	tango.io.Stdout,
	tango.core.Array,
	tango.net.SocketConduit,
	tango.net.InternetAddress,
	tango.net.Socket;
alias  tango.net.Socket.htons htons;
void main(){
	char[1024 * 2]	buf2;
	DNS_HEADER* dns	= cast(DNS_HEADER*) &buf2[0];
	dns.id	= htons(1);
	dns.rd	= htons(1);
	dns.q_count	= htons(1);
	int offset	= DNS_HEADER.sizeof  + ChangetoDnsNameFormat("www.baidu.com", buf2[ DNS_HEADER.sizeof .. $ ]) ;
	QUESTION* dnsq	= cast(QUESTION*) &buf2[ offset ];
	dnsq.qtype 	= htons(12);  //reverse DNS : adresse -> nom
	dnsq.qclass 	= htons(1);
	offset	+=	QUESTION.sizeof;
	
	Stdout.formatln("{}", buf2[0..offset+0]);
	
	auto soc	= new Socket(AddressFamily.INET, SocketType.DGRAM, ProtocolType.UDP);
	auto addr	= new InternetAddress("192.168.0.1", 55);
	soc.blocking(true);
	//soc.setLingerPeriod(1);
	if( soc.connect(addr)){
		soc.sendTo(buf2[0..offset], SocketFlags.NONE , addr);
		char[] buf	= new char[1024];
		int i	= soc.receiveFrom(buf, SocketFlags.NONE , addr);
		if( i > 0 && i< buf.length){
			Stdout.formatln("{}",  buf[0..i]);
		}else{
			Stdout.formatln("receiveFrom return :{} ",  i);
		}
		soc.detach();
	}
	
}

/*
DNS_HEADER
QTYPE:查询类型,两个八位组。表示:
A               1 主机地址
NS              2 授权管理域名服务器
CNAME           5 主机规范名字
SOA             6 授权开始
PTR             12 域名指针
MX              15 邮件服务器
QCLASS:IN或CH
*/

struct DNS_HEADER {
	WORD Xid ;			//A value that specifies the unique DNS message identifier.
	align(1):
	BYTE RecursionDesired ; //A value that specifies whether recursive name query should be used by the DNS name server.
					// 0x00 Do not use recursive name query.  
					// 0x01 Use recursive name query.
	BYTE Truncation ;	//A value that specifies whether the DNS message has been truncated.
					//0x00  The message is not truncated.
					//0x01  The message is truncated.
	BYTE Authoritative ;	//A value that specifies whether the DNS server from which the DNS message is being sent is authoritative for the domain name's zone.
					//0x00	The DNS server is not authoritative in the zone.
					//0x01	The DNS server is authoritative in the zone.
	align(4):
	BYTE Opcode ;		//A value that specifies the operation code to be taken on the DNS message as defined in section 4.1.1 of RFC 1035 as the OPCODE field.
	align(1):
	BYTE IsResponse  ;	//A value that specifies whether the DNS message is a query or a response message.
					//0x00	The DNS message is a query.
					//0x01	The DNS message is a response.
	align(4):
	BYTE ResponseCode  = 4 ;	//The DNS Response Code of the message.
	align(1):
	BYTE CheckingDisabled ;	//Windows 7 or later: A value that specifies whether checking is supported by the DNS resolver.
						//0x00	Checking is enabled on the DNS resolver.
						//0x01	Checking is disabled on the DNS resolver.
	BYTE AuthenticatedData   ;	//Windows 7 or later: A value that specifies whether the DNS data following the DNS_HEADER is authenticated by the DNS server.
						//0x00	The DNS data is not authenticated.
						//0x01	The DNS data is authenticated.
	BYTE Reserved  ;			//Reserved. Do not use.
	BYTE RecursionAvailable  ;	//A value that specifies whether recursive name query is supported by the DNS name server.
						//0x00	Recursive name query is not supported.
						//0x01	Recursive name query is supported.
	align(4):
	WORD QuestionCount ;		//The number of queries contained in the question section of the DNS message.
	WORD AnswerCount ;		//The number of resource records (RRs) contained in the answer section of the DNS message.
	WORD NameServerCount ;	//The number of DNS name server RRs contained in the authority section of the DNS message. This value is the number of DNS name servers the message has traversed in its search for resolution.
	WORD AdditionalCount ;	//Reserved. Do not use.
	
	alias	Xid	id;
	alias	CheckingDisabled rd;
	alias QuestionCount	q_count;
}

//set up the header
//dns->id = (unsigned short)htons(GetCurrentProcessId());
//dns->qr = 0; //This is a query
//dns->opcode = 0; //This is a standard query
//dns->aa = 0; //Not Authoritative
//dns->tc = 0; //This message is not truncated
//dns->rd = 1; //Recursion Desired
//dns->ra = 0; //Recursion not available! hey we dont have it (lol)
//dns->z = 0;
//dns->ad = 0;
//dns->cd = 0;
//dns->rcode = 0;
//dns->q_count = htons(1); //we have only 1 question
//dns->ans_count = 0;
//dns->auth_count = 0;
//dns->add_count = 0; 

struct QUESTION {
	WORD	qtype;
	WORD	qclass;
}

int ChangetoDnsNameFormat(char[] host, char[] buf){
	assert(buf.length > host.length);
	char* ptr	= &buf[0];
	int len;
	while(true){
		int i	= find(host, '.');
		if( i == host.length ){
			buf[0]	= i;
			buf[1..i+1]	= host;
			len	= &buf[i+2] - ptr;
			ptr[len-1] = 0;
			break;
		}
		buf[0]	= i;
		buf[1..i+1]	= host[0..i];
		host		= host[i+1..$];
		buf		= buf[i+1..$];
	}
	return len;
}
Global site tag (gtag.js) - Google Analytics