0

コードのこの部分で問題が発生しています。実際、クライアント/サーバー アプリケーションを設定したいと考えています。クライアント部分では、スレッドを起動します。この機能は、サーバーに接続されているかどうかを毎回チェックするだけです (サーバーへの接続がまだ確立されている場合)。TraceLog は、その Info() メソッドを使用してファイルに書き込むクラスです。これはクライアントコードです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;

namespace ClientApp
{
    class ClientOpenConnection
    {
        private static Thread threadConnect;
        static TcpClient myClient = new TcpClient();
        static String host = "";
        static Int32 port = 0;

        //Function that makes the client runs
        public static void RunClient(String hostname, Int32 hostport)
        {
            host = hostname;
            port = hostport;
            int _tryAgain = 0;

            while (!myClient.Connected) {
                try
                {   //I start the connection
                    myClient.Connect(host, port);
                }
                catch {

                }
                _tryAgain += 10;
                if (_tryAgain == 1000)
                    break;
                 //_tryAgain allows me to define how long will the client try to connect to the server.
            }
            TraceLog.Info("Out of the while ", ""); // This is to know where am I

            if (_tryAgain != 1000)
            {    //If I get out because _tryAgain is less than 1000. It means that I am already connected to the server
                //Here I start a Thread to be sure that I am always connected to the server
                threadConnect = new Thread(isConnected);
                threadConnect.Start();
                TraceLog.Info("Launch the thread","");
            }
            //While threadConnect is executing parallely I continue my program
        }

        private static void isConnected() { 
            //I keep my eyes on the network connection
            while (myClient.Connected) { 
                //Nothing is done
            }
            TraceLog.Info("The connection has been lost","");
            RunClient(host,port);
        }
    }
}

私が抱えている問題は、サーバーの前にクライアントを起動すると、最初の WHILE ループに入るということです。このレベルでOKです。後でサーバーを起動すると、threadConnectを起動しますが、問題は、サーバーを停止すると、通常はログファイル内に「接続が失われました」というメッセージが表示されるはずですが、何もありません。コードのこの部分の何が問題になっていますか? 過去にこのようなことをしたことがありますか?

変更を加えましたが、必要なものを取得するのにまだ問題があります。つまり、サーバーが停止している場合でも、クライアントは常にサーバーに接続しようとします。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;

namespace ClientApp
{
    class ClientOpenConnection
    {
        private static Thread threadConnect;
        static TcpClient myClient = new TcpClient();
        static String host = "";
        static Int32 port = 0;

        //Function that makes the client runs
        public static void RunClient(String hostname, Int32 hostport)
        {
            host = hostname;
            port = hostport;

            TraceLog.Info(" -> "+myClient.Connected,"");

            while (!myClient.Connected) {
                try
                {
                    myClient.Connect(host, port);
                    TraceLog.Info(" <-> " + myClient.Connected, "");
                }
                catch {
                    TraceLog.Info("Trying to contact the server","");
                }
            }
            TraceLog.Info("I am connected ", "");

            //Here I start a Thread to be sure that I am always connected to the server
            threadConnect = new Thread(isConnected);
            threadConnect.Start();
            TraceLog.Info("Launch the thread to be sure I am constantly online","");
        }

        private static void isConnected() { 
            //I keep my eyes on the network connection
            TraceLog.Info("->>"+myClient.Connected,"");
            while (myClient.Connected) {

                Thread.Sleep(500);

                try
                {
                    NetworkStream stream = myClient.GetStream();

                    ASCIIEncoding ascii = new ASCIIEncoding();

                    byte[] _incomingMsg = new byte[1024];

                    stream.Read(_incomingMsg, 0, _incomingMsg.Length);

                    String strToGet = System.Text.Encoding.ASCII.GetString(_incomingMsg);

                    strToGet = strToGet.Trim();

                    if (!strToGet.Equals("ONLINE"))
                        if (strToGet.Equals(""))
                        {
                            TraceLog.Info("The message receive is empty","");
                            break;
                        }
                }
                catch {
                    break;
                }
            }          
            TraceLog.Info("The connection has been lost", "");
            RunClient(host, port);
        }
    }
}

しかし、isConnected() 関数で RunClient() を呼び出すと、WHILE で実行され、TraceLog.Info("Trying to contact the server",""); が出力されます。サーバーを再起動しても、クライアントは while ループにとどまり、まったく接続されません。

4

1 に答える 1

2

MSDNから:

Connected プロパティは、最後の I/O 操作の時点でのクライアント ソケットの接続状態を取得します。false が返された場合、クライアント ソケットは接続されていなかったか、接続されていません。

Connected プロパティは、最新の操作の時点での接続の状態のみを反映するため、現在の状態を判断するには、メッセージの送受信を試みる必要があります。メッセージの送信が失敗すると、このプロパティは true を返さなくなります。この動作は仕様によるものであることに注意してください。テストと送受信の間に接続が失われた可能性があるため、接続の状態を確実にテストすることはできません。コードは、ソケットが接続されていると想定し、失敗した送信を適切に処理する必要があります。

つまり、まだ接続されているかどうかを確認するには、データを送受信してから接続状態を確認する必要があります。

コードは接続後にパケットを送信しないため、connected プロパティは常に true を返し、ループは終了しません。

于 2012-05-10T19:25:59.000 に答える