Java将udp数据包发送到dns服务器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java将udp数据包发送到dns服务器相关的知识,希望对你有一定的参考价值。
我正在尝试将udp数据包发送到特定的DNS服务器并从dns服务器接收响应。
问题是我不会从服务器得到响应。我尝试使用我的客户端套接字接收数据包,但没有任何成功。
寻求帮助来解决这个问题。
这是我的UdpClient.java
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
class UdpClient
{
public static void main (String args[]) throws Exception
{
Scanner scan = new Scanner(System.in);
System.out.print("Enter a hostname: ");
// host name
String hostname = scan.next();
// socket
DatagramSocket clientSocket = new DatagramSocket();
InetAddress ipAddress = InetAddress.getByName(hostname);
String message = "0471001000000";
byte[] data = message.getBytes(StandardCharsets.UTF_8);
// datagram packet
DatagramPacket sendPacket = new DatagramPacket(data, data.length, ipAddress, 53);
// send the packet
clientSocket.send(sendPacket);
// set a receive timeout, 2000 milliseconds
// packet for receive
byte[] rdata = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(rdata, rdata.length, ipAddress, 53);
// wait for a response from the server
clientSocket.receive(receivePacket);
System.out.println("Host Name: " + ipAddress.getHostName());
System.out.println("Canonical Host Name: " + ipAddress.getCanonicalHostName());
System.out.println("Local Host: " + ipAddress.getLocalHost());
System.out.println("Loopback Address: " + ipAddress.getLoopbackAddress());
System.out.println("IPv4: " + ipAddress.getHostAddress());
String serverMessage = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("FROM SERVER: " + serverMessage);
}
}
答案
以下是通过UDP查询DNS记录并打印结果的快速而肮脏的示例:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* A quick and dirty example of query DNS A record and log response.
* This code has no error handling.
*
*/
public class DNSClient {
private static final String DNS_SERVER_ADDRESS = "8.8.8.8";
private static final int DNS_SERVER_PORT = 53;
public static void main(String[] args) throws IOException {
String domain = "google.com";
InetAddress ipAddress = InetAddress.getByName(DNS_SERVER_ADDRESS);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
// *** Build a DNS Request Frame ****
// Identifier: A 16-bit identification field generated by the device that creates the DNS query.
// It is copied by the server into the response, so it can be used by that device to match that
// query to the corresponding reply received from a DNS server. This is used in a manner similar
// to how the Identifier field is used in many of the ICMP message types.
dos.writeShort(0x1234);
// Write Query Flags
dos.writeShort(0x0100);
// Question Count: Specifies the number of questions in the Question section of the message.
dos.writeShort(0x0001);
// Answer Record Count: Specifies the number of resource records in the Answer section of the message.
dos.writeShort(0x0000);
// Authority Record Count: Specifies the number of resource records in the Authority section of
// the message. (“NS” stands for “name server”)
dos.writeShort(0x0000);
// Additional Record Count: Specifies the number of resource records in the Additional section of the message.
dos.writeShort(0x0000);
String[] domainParts = domain.split("\.");
System.out.println(domain + " has " + domainParts.length + " parts");
for (int i = 0; i<domainParts.length; i++) {
System.out.println("Writing: " + domainParts[i]);
byte[] domainBytes = domainParts[i].getBytes("UTF-8");
dos.writeByte(domainBytes.length);
dos.write(domainBytes);
}
// No more parts
dos.writeByte(0x00);
// Type 0x01 = A (Host Request)
dos.writeShort(0x0001);
// Class 0x01 = IN
dos.writeShort(0x0001);
byte[] dnsFrame = baos.toByteArray();
System.out.println("Sending: " + dnsFrame.length + " bytes");
for (int i =0; i< dnsFrame.length; i++) {
System.out.print("0x" + String.format("%x", dnsFrame[i]) + " " );
}
// *** Send DNS Request Frame ***
DatagramSocket socket = new DatagramSocket();
DatagramPacket dnsReqPacket = new DatagramPacket(dnsFrame, dnsFrame.length, ipAddress, DNS_SERVER_PORT);
socket.send(dnsReqPacket);
// Await response from DNS server
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
System.out.println("
Received: " + packet.getLength() + " bytes");
for (int i = 0; i < packet.getLength(); i++) {
System.out.print(" 0x" + String.format("%x", buf[i]) + " " );
}
System.out.println("
");
DataInputStream din = new DataInputStream(new ByteArrayInputStream(buf));
System.out.println("Transaction ID: 0x" + String.format("%x", din.readShort()));
System.out.println("Flags: 0x" + String.format("%x", din.readShort()));
System.out.println("Questions: 0x" + String.format("%x", din.readShort()));
System.out.println("Answers RRs: 0x" + String.format("%x", din.readShort()));
System.out.println("Authority RRs: 0x" + String.format("%x", din.readShort()));
System.out.println("Additional RRs: 0x" + String.format("%x", din.readShort()));
int recLen = 0;
while ((recLen = din.readByte()) > 0) {
byte[] record = new byte[recLen];
for (int i = 0; i < recLen; i++) {
record[i] = din.readByte();
}
System.out.println("Record: " + new String(record, "UTF-8"));
}
System.out.println("Record Type: 0x" + String.format("%x", din.readShort()));
System.out.println("Class: 0x" + String.format("%x", din.readShort()));
System.out.println("Field: 0x" + String.format("%x", din.readShort()));
System.out.println("Type: 0x" + String.format("%x", din.readShort()));
System.out.println("Class: 0x" + String.format("%x", din.readShort()));
System.out.println("TTL: 0x" + String.format("%x", din.readInt()));
short addrLen = din.readShort();
System.out.println("Len: 0x" + String.format("%x", addrLen));
System.out.print("Address: ");
for (int i = 0; i < addrLen; i++ ) {
System.out.print("" + String.format("%d", (din.readByte() & 0xFF)) + ".");
}
}
}
以上是关于Java将udp数据包发送到dns服务器的主要内容,如果未能解决你的问题,请参考以下文章