Ich schreibe eine Netzwerkschicht über TCP und ich habe einige Probleme während meiner UnitTest-Phase. HierTcpClient entsorgen
ist, was ich tue (Meine Bibliothek besteht aus mehreren Klassen bestehen aber zeige ich Ihnen nur die nativen Befehle meine Probleme zu verursachen, um die Größe der Post zu begrenzen):
private const int SERVER_PORT = 15000;
private const int CLIENT_PORT = 16000;
private const string LOCALHOST = "127.0.0.1";
private TcpClient Client { get; set; }
private TcpListener ServerListener { get; set; }
private TcpClient Server { get; set; }
[TestInitialize]
public void MyTestInitialize()
{
this.ServerListener = new TcpListener(new IPEndPoint(IPAddress.Parse(LOCALHOST), SERVER_PORT));
this.Client = new TcpClient(new IPEndPoint(IPAddress.Parse(LOCALHOST), CLIENT_PORT));
this.ServerListener.Start();
}
// In this method, I just try to connect to the server
[TestMethod]
public void TestConnect1()
{
var connectionRequest = this.ServerListener.AcceptTcpClientAsync();
this.Client.Connect(LOCALHOST, SERVER_PORT);
connectionRequest.Wait();
this.Server = connectionRequest.Result;
}
// In this method, I assume there is an applicative error within the client and it is disposed
[TestMethod]
public void TestConnect2()
{
var connectionRequest = this.ServerListener.AcceptTcpClientAsync();
this.Client.Connect(LOCALHOST, SERVER_PORT);
connectionRequest.Wait();
this.Server = connectionRequest.Result;
this.Client.Dispose();
}
[TestCleanup]
public void MyTestCleanup()
{
this.ServerListener?.Stop();
this.Server?.Dispose();
this.Client?.Dispose();
}
Zu allererst , HAVE TO Entsorgen Sie den Server zuerst, wenn ich eine frühere Verbindung vom gleichen Endpunkt zum selben Server herstellen möchte:
Wenn Sie meine Tests so ausführen, wird es beim ersten Mal erfolgreich ausgeführt. Beim zweiten Mal wird in beiden Tests eine Ausnahme auf die Methode Connect
ausgelöst, da der Port bereits verwendet wird. Die einzige Möglichkeit, diese Ausnahme zu vermeiden (und eine Verbindung auf demselben Listener vom selben Endpunkt aus herstellen zu können) besteht darin, eine SocketException innerhalb des Servers durch zweimaliges Senden von Bytes an den entsorgten Client zu provozieren (beim ersten Senden) es gibt kein Problem, die Ausnahme wird nur beim zweiten Senden ausgelöst).
Ich brauche nicht einmal die Server
zu entsorgen, wenn ich eine Ausnahme provozieren ...
Warum ist die Server.Dispose()
schließt nicht die Verbindung und den Anschluss zu befreien ??? Gibt es eine bessere Möglichkeit, den Hafen zu befreien, als eine Ausnahme zu provozieren?
Vielen Dank im Voraus.
(Sorry für mein Englisch, ich bin kein Muttersprachler)
Hier ist ein Beispiel innerhalb eines Haupt fonction, um Kasse leichter:
private const int SERVER_PORT = 15000;
private const int CLIENT_PORT = 16000;
private const string LOCALHOST = "127.0.0.1";
static void Main(string[] args)
{
var serverListener = new TcpListener(new IPEndPoint(IPAddress.Parse(LOCALHOST), SERVER_PORT));
var client = new TcpClient(new IPEndPoint(IPAddress.Parse(LOCALHOST), CLIENT_PORT));
serverListener.Start();
var connectionRequest = client.ConnectAsync(LOCALHOST, SERVER_PORT);
var server = serverListener.AcceptTcpClient();
connectionRequest.Wait();
// Oops, something wrong append (wrong password for exemple), the client has to be disposed (I really want this behavior)
client.Dispose();
// Uncomment this to see the magic happens
//try
//{
//server.Client.Send(Encoding.ASCII.GetBytes("no problem"));
//server.Client.Send(Encoding.ASCII.GetBytes("oops looks like the client is disconnected"));
//}
//catch (Exception)
//{ }
// Lets try again, with a new password for example (as I said, I really want to close the connection in the first place, and I need to keep the same client EndPoint !)
client = new TcpClient(new IPEndPoint(IPAddress.Parse(LOCALHOST), CLIENT_PORT));
connectionRequest = client.ConnectAsync(LOCALHOST, SERVER_PORT);
// If the previous try/catch is commented, you will stay stuck here,
// because the ConnectAsync has thrown an exception that will be raised only during the Wait() instruction
server = serverListener.AcceptTcpClient();
connectionRequest.Wait();
Console.WriteLine("press a key");
Console.ReadKey();
}
Sie müssen möglicherweise zu Starten Sie Visual Studio neu (oder warten Sie einige Zeit), wenn Sie den Fehler auslösen und das Programm sich weigert, eine Verbindung herzustellen.
Sie scheinen .NET zu testen 'TcpClient' und' TcpListener'. Sie sollten Ihren eigenen Code testen, nicht das Framework. –
Wie gesagt, ich schreibe eine Netzwerkschicht über Tcp. Aber ich zeige dir nur die Anweisungen, die mir Probleme bereiten. Ich zeige sie dir nicht in meinem ganzen eingekapselten Code, um dich nicht zu überfluten. Ich werde meine Einführung bearbeiten, um expliziter zu sein! – fharreau