4

C# に TCP トンネルがあります。サーバーとクライアントの間のアプリであるトンネルを開閉する必要があります。これを使用してデータ接続を閉じ、別のアプリをテストしています。特定のポートを使用する必要があります。

2 番目、3 番目、n 番目の接続で、再接続までの待機時間に応じて、ソケットをバインドするときに「アドレスは既に使用されています」という 10048 エラー コードが表示されます。ソケットを閉じるときは、ポートをクリアすることを期待して ShutDown.Both と Close を実行しますが、コマンド プロンプトで netstat を実行すると、まだポートが TIME_WAIT に保持されていることがわかります。また、ソケットをノーリンガーに設定しました。最後にポートの状態を確認するループを作ってみたのですが、なんだか無限ループに陥ってしまいます。4分のTIME_WAITルールだと思います。

nestatクエリを表示する関数があり、それを実行すると、ポートがESTABLISHEDからバインドできるTIME_WAITになるまでチェックすることがわかりましたが、このクエリの同じデータを使用してループでバインドすると、ステータスが TIME_WAIT に達し、10048 が表示されます。ボタンのクリックによってバインドできるようになる短い時間はありますか? TIME_WAIT と ESTABLISHED の間に状態はありますか? ボタンをクリックしたときではなく、ループでヒットしていますか? TIME_WAIT はバインドを完全に停止する必要があると読みましたが、これは正しくないようです。誰でもこれを説明できますか?

コード愛好家の皆様、申し訳ありません。しかし、これで何かが変わるとは考えていません。ポートの状態をよりよく理解する必要があります。

    public bool CheckAvailablePorts()
    {
        int temp=0;
        bool availPort= true;
        m_config = new AppConfig();
        if (!m_config.initialize())
        {
            System.Diagnostics.Debug.WriteLine("Error loading configuration file.  Exiting...");
            return false;
        }
        else
        {

//checking through all the ports that have been set to connect on

            foreach (ProxyConfig cfg in m_config.m_proxyConfigs)
            {
                availPort = true;
                temp = cfg.localEP.Port;
                DataView dv = FindEstablishedSockets();//returns netstat query
                foreach (DataRowView rowView in dv)
                {
                    DataRow row = rowView.Row;

                    if ((Convert.ToInt32(row["Local Port"].ToString()) == temp) && (row["Status"].ToString().Equals("Established")))
                    {
                        System.Diagnostics.Debug.WriteLine("Port: " + temp + " is still locked");
                        availPort = false;
                        break;
                    }
                }
            }
            return availPort;
        }
    }

//snippet out of a bigger function which checks for availability and then sleeps if false and runs again

            bool temp = false;
            while (!temp)
            {
                temp = monitor.CheckAvailablePorts();
                System.Threading.Thread.Sleep(2000);
            }
            System.Threading.Thread.Sleep(3000);
            monitor.startApplication(); //starts all the binding
4

3 に答える 3

0

TIME_WAIT はバインドを完全に停止する必要があると読みましたが、これは正しくないようです。

TIME_WAIT にあるローカル ポートをバインドできるオプションがあります。これは、サーバーを強制終了してから再起動するまで 4 分間待つ必要がないようにするのに非常に便利です。

int flag = 1;
sockfd = socket(...);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
bind(...);
于 2011-04-20T12:44:43.593 に答える
0

自分が何をしているのかを知るのは難しいので、もう少し具体的にする必要があります。短いテキストとコード サンプルが役立ちます。

接続を開いたり閉じたりしてから、もう一度開く必要があります

それがクライアントにある場合、それは問題にはなりません。サーバー側の場合は、その理由を説明してください。

サーバー上の構成ファイルは特定のポートを探しているため、再接続するときは同じポートを再度開く必要があります

どう言う意味ですか?リスニング ポートを意味する場合: リスナー ソケットを閉じないでください。複数のソケットを受け入れたくない場合はAccept、クライアント ソケットが切断されるまで再度呼び出さないでください。

于 2011-04-08T13:00:05.310 に答える
-2

ソケットを閉じる前に、ピアから送信されたすべてのデータを読み取る必要があります。そうしないと、新しいソケットが前のソケット(閉じたソケット)用のデータを読み取らないように、TIME_WAITに留まります。ソケットの長引くオプションを試すこともできます。

詳細: http: //msdn.microsoft.com/en-us/library/windows/desktop/ms738547%28v=vs.85%29.aspx

于 2012-02-02T08:58:47.490 に答える