1

サーバーとの間でデータを送受信するためのアプリケーションを作成しています。データを送信する前に接続を確立し、ユーザーがデータを継続的に送信できるように接続を開いたままにしておく必要があります。ユーザーは、切断ボタンをクリックすることにより、いつでも接続を閉じることができます。接続用と切断用の2つのボタンを作成しました。切断ボタンの背後にあるコードは次のとおりです:-

    private void button1_Click(object sender, EventArgs e)
    {
        if (tcpclnt.Connected)
        {
            tcpclnt.Client.Disconnect(false);
            stm.Close();
        }
        else
        {
            MessageBox.Show("Not Connected");
        }
    }

接続ボタンの背後にあるコードは次のとおりです:-

    public ASCIIEncoding asen = new ASCIIEncoding();
    public TcpClient tcpclnt = new TcpClient();
    public NetworkStream stm;

    private void Connect_Click(object sender, EventArgs e)
    {
        if (!tcpclnt.Connected)
        {                
            tcpclnt.Connect("XX.XX.XX.XX", 5500);
            MessageBox.Show("Connected to server");


            stm = tcpclnt.GetStream();

            string sysname = "000B0000" + SystemName.Text.ToString();
            byte[] sys1 = asen.GetBytes(sysname);
            sys1[0] = 0; sys1[1] = 0;
            sys1[2] = 0; sys1[3] = 0xB;
            sys1[4] = 0; sys1[5] = 0;
            sys1[6] = 0; sys1[7] = 0;
            try
            {
                stm.Write(sys1, 0, sys1.Length);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                MessageBox.Show("Error in Sending data");
            }
            if (stm.DataAvailable)
            {
                try
                {
                    byte[] bb = new byte[600];
                    int k = 8;                        
                    k = stm.Read(bb, 0, bb.Length);
                    string value = ASCIIEncoding.ASCII.GetString(bb, 8, k - 8);
                    MessageBox.Show(value.ToString());
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    MessageBox.Show("Error in Reading data");
                }
            }                
         }
         else {
                MessageBox.Show("Already Connected");
        }
    } 

ここで、[切断]ボタンをクリックしてから、もう一度[接続]ボタンをクリックすると、tcpclient.connect行で例外がスローされます。なぜ、どうすれば解決できるのかわかりません。

4

2 に答える 2

1

このトピックの専門家ではありませんが、可能な解決策は tcpclnt.Close() を使用して接続を適切に閉じることだと思います。これを行わなかったり、ガベージ コレクタに不当に行わせたりすると、再接続できなくなります (私はそう思います)。ストリームを閉じてから、切断するのではなく tcpclnt を閉じます。

tcpclnt.GetStream().Close();
tcpclnt.Close();

また、接続があるかどうかを確認するために tcpclnt.Connected を使用しないでください。単に閉じてください。

編集

上記は機能しません。ソケットの再利用方法がわかりません。これが私がそれを機能させる方法です...

private void DisconnectButton_Click(object sender, EventArgs e)
{
    tcpclnt.Close();
    tcpclnt = new TcpClient();
}

オブジェクトを再インスタンス化すると、追加のスレッドが作成されると述べました。これをテストする方法がわからないので、これは本当かもしれません。Windows リソース モニターを開いてアプリのスレッド カウントを確認しましたが、毎回追加のスレッドが開いていることは示されませんでした。

于 2012-07-01T05:50:34.900 に答える
0

.Disconnect() 呼び出しには、再利用を許可するパラメーターとして true が必要です。現在、再接続を許可しないようにソケットに指示しています。ドキュメントについては、こちらを参照してください。

于 2012-07-01T01:54:43.200 に答える