【发布时间】:2017-01-06 19:05:49
【问题描述】:
我现在拥有的是通过 UDP 进行的 DNS 查询,它工作正常,但如果消息被截断,我需要使用相同的查询通过 TCP 重新连接,我不能这样做,主要问题是我确实有字节查询数组和 tcp 发送字符。
我的 UDP 查询组装:
String DNS_SERVER_ADDRESS = args[0];
String domain = args[1];
ipAddress = InetAddress.getByName(DNS_SERVER_ADDRESS);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
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);
// TODO: write query
String[] domainParts = domain.split("\\.");
System.out.println(domain + " has " + domainParts.length + " parts");
for (String domainPart : domainParts) {
System.out.println("Writing: " + domainPart);
byte[] domainBytes = domainPart.getBytes("UTF-8");
dos.writeByte(domainBytes.length);
dos.write(domainBytes);
}
// No more parts
dos.writeByte(0x00);
// QType 0x01 = A (Host Request)
if (args.length>2)
dos.writeShort(typeEncode(args[2]));
else
dos.writeShort(0x00ff); // "ANY" as default
// QClass 0x01 = IN
dos.writeShort(0x0001);
dnsFrame = baos.toByteArray();
System.out.println("Sending: " + dnsFrame.length + " bytes");
for (byte aDnsFrame : dnsFrame) {
System.out.print("0x" + String.format("%x", aDnsFrame) + " ");
}
// *** Send DNS Request Frame ***
DatagramSocket socket = new DatagramSocket();
DatagramPacket dnsReqPacket = new DatagramPacket(dnsFrame, dnsFrame.length, ipAddress, DNS_SERVER_PORT);
socket.send(dnsReqPacket);
return socket;
我如何尝试通过 TCP 发送它:
Socket echoSocket = null;
// strumień do zapisu do serwera
Writer out = null;
// strumień do odczytu z serwera
BufferedReader in = null;
// nazwa serwera
String hostname=args[0];
try {
System.out.println("próba utworzenia gniazda");
echoSocket = new Socket(ipAddress, DNS_SERVER_PORT);
System.out.println("próba utworzenia strumienia wyjściowego");
out = new PrintWriter(echoSocket.getOutputStream(), true);
OutputStream outputStream = echoSocket.getOutputStream();
System.out.println("próba utworzenia strumienia wejściowego");
in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
ObjectOutputStream os = new ObjectOutputStream(echoSocket.getOutputStream());
os.flush();
ObjectInputStream is = new ObjectInputStream(echoSocket.getInputStream());
os.writeObject(dnsFrame);
byte[] temp = (byte[]) is.readObject();
} catch (UnknownHostException e) {
System.err.println("Nieznany host: " + hostname + ".");
System.exit(1);
} catch (IOException e) {
System.err.println("Błąd połączenia z " + hostname + ".");
System.exit(1);
}
// zakończenie pracy - pozamykaj strumienie i gniazda
out.close();
in.close();
echoSocket.close();
我使用wireshark读取我在TCP中实际发送的内容,它与UDP不同,所以我认为问题在于发送字节数组的过程中。
【问题讨论】:
-
"tcp sent chars" -- 是什么让你认为这是真的?
ObjectOutputStream用于 Java 对象,与DataOutputStream非常不同。您的 TCP 和 UDP 版本非常不同。 -
TCP 发送 八位字节。您不应该使用
Readers和Writers,您应该使用与YDP 相同的DataInput/OutputStream,确实非常相同的代码,但使用Socket.getInput/OutputStream()作为底层流而不是ByteArrayInput/OutputStreams.
标签: java sockets networking tcp dns