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 循环。在这个级别上是可以的。当我启动服务器之后,我启动了 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 回答