mirror of
https://github.com/netchx/netch.git
synced 2026-03-28 18:59:46 +08:00
73 lines
2.2 KiB
C#
73 lines
2.2 KiB
C#
using DNS.Protocol;
|
|
using System;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace DNS.Client.RequestResolver
|
|
{
|
|
public class TcpRequestResolver : IRequestResolver
|
|
{
|
|
private IPEndPoint dns;
|
|
|
|
public TcpRequestResolver(IPEndPoint dns)
|
|
{
|
|
this.dns = dns;
|
|
}
|
|
|
|
public async Task<IResponse> Resolve(IRequest request, CancellationToken cancellationToken = default(CancellationToken))
|
|
{
|
|
using (TcpClient tcp = new TcpClient())
|
|
{
|
|
await tcp.ConnectAsync(dns.Address, dns.Port);
|
|
|
|
Stream stream = tcp.GetStream();
|
|
byte[] buffer = request.ToArray();
|
|
byte[] length = BitConverter.GetBytes((ushort)buffer.Length);
|
|
|
|
if (BitConverter.IsLittleEndian)
|
|
{
|
|
Array.Reverse(length);
|
|
}
|
|
|
|
await stream.WriteAsync(length, 0, length.Length, cancellationToken);
|
|
await stream.WriteAsync(buffer, 0, buffer.Length, cancellationToken);
|
|
|
|
buffer = new byte[2];
|
|
await Read(stream, buffer, cancellationToken);
|
|
|
|
if (BitConverter.IsLittleEndian)
|
|
{
|
|
Array.Reverse(buffer);
|
|
}
|
|
|
|
buffer = new byte[BitConverter.ToUInt16(buffer, 0)];
|
|
await Read(stream, buffer, cancellationToken);
|
|
|
|
IResponse response = Response.FromArray(buffer);
|
|
return new ClientResponse(request, response, buffer);
|
|
}
|
|
}
|
|
|
|
private static async Task Read(Stream stream, byte[] buffer, CancellationToken cancellationToken)
|
|
{
|
|
int length = buffer.Length;
|
|
int offset = 0;
|
|
int size = 0;
|
|
|
|
while (length > 0 && (size = await stream.ReadAsync(buffer, offset, length, cancellationToken)) > 0)
|
|
{
|
|
offset += size;
|
|
length -= size;
|
|
}
|
|
|
|
if (length > 0)
|
|
{
|
|
throw new IOException("Unexpected end of stream");
|
|
}
|
|
}
|
|
}
|
|
}
|