私はTCPの上にネットワーク層を作成しています。私はUnitTest段階でいくつかの問題に直面しています。すべてのTcpClientは注文を処理します
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();
}
まず:ここ
は、私は(私のライブラリが複数のクラスで構成されているが、私は唯一のポストのサイズを制限するために、あなたに私の問題を引き起こしてネイティブ命令を示して)やっているものです、があります同じエンドポイントから同じポートのサーバに先に接続したい場合は、先にサーバを破棄してください。
このようなテストを実行すると、初めて正常に実行されます。 2回目のテストでは、ポートがすでに使用中であると主張して、Connect
メソッドで例外がスローされます。
この例外を回避し(同じエンドポイントから同じリスナーに接続できるようにするために)、唯一の方法は、サーバー内でSocketExceptionを引き起こすことです。 、問題はありません。例外は2回目の送信時にのみスローされます)。
私も、私は例外を引き起こす場合...
はなぜServer.Dispose()
が接続を閉じるとポートを解放されていないServer
を廃棄する必要はありません?例外を引き起こすよりもポートを解放する方がいいですか?
ありがとうございます。
は(私の英語のため申し訳ありませんが、私はネイティブスピーカーではないよ)
ここでチェックアウトより簡単にするために、メインfonction内の例です:
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();
}
あなたがする必要があるかもしれませんバグを引き起こし、プログラムが接続を拒否した場合、Visual Studioを再起動してください(またはしばらくお待ちください)。
.NETのテストを行っているようです'TcpClient'と' TcpListener'です。フレームワークではなく、独自のコードをテストする必要があります。 –
私が言ったように、私はTcpの上にネットワーク層を書いています。しかし、私は悩みの原因となる指示だけをあなたに示します。私はカプセル化されたコードの中に、あなたを溢れさせないためにそれらを見せません。より明示的に私の紹介を編集します! – fharreau