我正在嘗試使用我的 Socket 包裝器連接到指定的 whois 服務器以接收一些資訊(是的,我知道 TcpClient 存在)。為此,我做了兩節課。一 - SocketClient - 接受 Socket 并具有處理所有連接內容的方法。(我沒有包括 IDisposable 實作)
public class SocketClient : ISocketClient
{
private const int HEADER_SIZE = 4;
private Socket _socket;
private bool disposedValue;
public SocketClient(Socket socket) { _socket = socket; }
public virtual Stream Connect(IPEndPoint endPoint)
{
_socket.Connect(endPoint);
return new NetworkStream(_socket);
}
public void Send(Stream networkStream, string message, Encoding encoding)
{
var bodyBytes = encoding.GetBytes(message);
var headerBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(bodyBytes.Length HEADER_SIZE));
networkStream.Write(headerBytes, 0, HEADER_SIZE);
networkStream.Write(bodyBytes, 0, bodyBytes.Length);
}
public string Receive(Stream networkStream)
{
var header = ReadStream(networkStream, HEADER_SIZE);
var bodyLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(header)) -HEADER_SIZE;
var bodyBytes = ReadStream(networkStream, bodyLength); //Here exception is thrown
return Encoding.UTF8.GetString(bodyBytes);
}
static byte[] ReadStream(Stream networkStream, int bytesToRead)
{
var buffer = new byte[bytesToRead];
var bytesRead = 0;
while (bytesRead < bytesToRead)
{
var bytesReceived = networkStream.Read(buffer, bytesRead, bytesToRead - bytesRead);
if (bytesReceived == 0)
throw new SocketIsClosedException("Tried to read from closed socket.");
bytesRead = bytesReceived;
}
return buffer;
}
第二 - WhoisResolver - 接受 SocketClient 并使用它來發送和接收 whois 資訊。
public class WhoisResolver : IWhoisResolver
{
private ISocketClient _socketClient;
private bool disposedValue;
public WhoisResolver(ISocketClient socketClient)
{
_socketClient = socketClient;
}
public string? Lookup(string fullDomainName, string whoisServerAddress, int whoisServerPort = 43)
{
try
{
var ip = Dns.GetHostAddresses(whoisServerAddress).First();
var stream = _socketClient.Connect(new IPEndPoint(ip, whoisServerPort));
_socketClient.Send(stream, $"{fullDomainName}\r\n",System.Text.Encoding.ASCII); //Here socket is still open
var response = _socketClient.Receive(stream);
_socketClient.Disconnect(false);
return response;
}catch
{
return null;
}
}
}
這是我如何使用它:
var whoisServer = "whois.crsnic.net";
var domainName = "testdomain";
var tld = "net";
var socketClient = new SocketClient(new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp));
var resolver = new WhoisResolver(socketClient);
var result = resolver.Lookup($"{domainName}.{tld}", whoisServer);
每次我的程式嘗試從流中讀取時,我都會隨機得到兩種例外:
- 無法從傳輸連接讀取資料:現有連接被遠程主機強行關閉。
-試圖從關閉的套接字中讀取。
當我使用帶有緩沖流和流讀取器/寫入器的 TcpClient 時,一切正常。
uj5u.com熱心網友回復:
如上面的評論所述,問題在于閱讀訊息長度的方式。我認為訊息頭是前 4 個位元組,但是當我閱讀它時,它的訊息長度超過了 20000000 個位元組。似乎很明顯,但例外情況非常具有誤導性。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/483733.html
標籤:C# asp.net 核心 插座 联网 .net-6.0
上一篇:SQLServer表轉換
