0

非同期スキャンを使用して、一度に複数のポートをスキャンしようとしています。問題は、最初の動作中のポートしか表示できず、ポートが閉じられていることを通知せずにアプリが閉じられるのを 20 秒ほど待つことです。

このコードの何が問題なのですか?

private void btnStart_Click(object sender, EventArgs e)
{
    for (int port = 80; port < 100; port++)
    {
        ScanPort(port);
    }
}

private void ScanPort(int port)
{
    var client = new TcpClient();

    try 
    {
        client.BeginConnect(IPAddress.Parse("74.125.226.84"), port, new AsyncCallback(CallBack), client);
    } 
    catch (SocketException) 
    {
        client.Close();
    }
}

private void CallBack(IAsyncResult result)
{
    var client = (TcpClient)result.AsyncState;

    client.EndConnect(result);

    if (client.Connected)
    {
        this.Invoke((MethodInvoker)delegate
        {
            txtDisplay.Text += "open2" + Environment.NewLine;
        });
    }
    else
    {
        this.Invoke((MethodInvoker)delegate
        {
            txtDisplay.Text += "closed2" + Environment.NewLine;
        });
    }
}
4

1 に答える 1

1

コールバック メソッドでは、接続を閉じて TcpClient を破棄するようにします。また、TcpClient.EndConnect(IAsyncResult) も例外をスローできます。また、ユーザーに表示するためにポート番号をキャプチャする場所もわかりません。コールバックを次のように記述します。

編集:実際にコードをコンパイルまたは実行しませんでした(申し訳ありません)。 また、C# でポート スキャナーを作成する方法を示すこの他の記事も見つけました。 http://www.dijksterhuis.org/building-a-simple-portscanner-in-c/

ここに落とし穴があります: TCPClient.Close() 関数の .NET 実装は、実際には接続を適切に閉じません。そのため、TCPClient.Close を呼び出す前に、接続を表すストリームを取得し、これを閉じるという追加の手順を実行する必要があります。

private void CallBack(IAsyncResult result) 
{ 
    var client = (TcpClient)result.AsyncState; 
    bool connected = false;

    try
    {
        client.EndConnect(result);
        connected = client.Connected;
    }
    catch (SocketException)
    {
    }
    catch (ObjectDisposedException)
    {
    }
    finally
    {
        if (client.Connected)
        {
            client.Close();
        }

        client.Dispose();
    }

    if (connected) 
    { 
        this.Invoke((MethodInvoker)delegate 
        { 
            txtDisplay.Text += "open2" + Environment.NewLine; 
        }); 
    } 
    else 
    { 
        this.Invoke((MethodInvoker)delegate 
        { 
            txtDisplay.Text += "closed2" + Environment.NewLine; 
        }); 
    } 
} 
于 2012-01-26T18:19:19.557 に答える