SUPER_CRJ 发表于 2018-8-3 15:32:27

C#如何快速的查找可用的TCP服务器

当前电脑用作TCP客户端,TCP服务器与客户端都在一个子网内。TCP服务器不最多有64个,地址也就是:192.168.1.x,服务器端口号固定为5000,现在有什么方法可以判断当前子网有多少个这样的服务器。现在用的方法是:用try{}catch{}尝试连接,如果不出错,就认为存在,但是发现搜索一个子网速度比较慢,有没有快速的方法?

leafstamen 发表于 2018-8-3 15:36:35

udp广播一个包,然后服务器给你回一下。
后续再用tcp实现你的逻辑。

SUPER_CRJ 发表于 2018-8-3 15:51:21

本帖最后由 SUPER_CRJ 于 2018-8-3 15:53 编辑

leafstamen 发表于 2018-8-3 15:36
udp广播一个包,然后服务器给你回一下。
后续再用tcp实现你的逻辑。

好方法,但是有没有不用UDP的?现在尝试连接等待出错连接不上要几秒的时间。
而且一个问题:UDP能给TCP服务器发消息?

longlong105 发表于 2018-8-3 16:10:50

TCP超时时间设置!
本class 来自网络,目前我正在使用!

使用方法TimeOutSocket.Connect(IPPoint, SocketTimeout);

class TimeOutTcpClient
    {
      private static bool IsConnectionSuccessful = false;
      private static Exception socketexception;
      private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);

      public static TcpClient Connect(IPEndPoint remoteEndPoint, int timeoutMSec)
      {
            TimeoutObject.Reset();
            socketexception = null;

            string serverip = Convert.ToString(remoteEndPoint.Address);
            int serverport = remoteEndPoint.Port;
            TcpClient tcpclient = new TcpClient();

            tcpclient.BeginConnect(serverip, serverport,
                new AsyncCallback(CallBackMethod), tcpclient);

            if (TimeoutObject.WaitOne(timeoutMSec, false))
            {
                if (IsConnectionSuccessful)
                {
                  return tcpclient;
                }
                else
                {
                  throw socketexception;
                }
            }
            else
            {
                tcpclient.Close();
                throw new TimeoutException("Connection TimeOut");
            }
      }
      private static void CallBackMethod(IAsyncResult asyncresult)
      {
            try
            {
                IsConnectionSuccessful = false;
                TcpClient tcpclient = asyncresult.AsyncState as TcpClient;

                if (tcpclient.Client != null)
                {
                  tcpclient.EndConnect(asyncresult);
                  IsConnectionSuccessful = true;
                }
            }
            catch (Exception ex)
            {
                IsConnectionSuccessful = false;
                socketexception = ex;
            }
            finally
            {
                TimeoutObject.Set();
            }
      }
    }


    class TimeOutSocket
    {
      private static bool IsConnectionSuccessful = false;
      private static Exception socketexception;
      private static System.Threading.ManualResetEvent TimeoutObject = new System.Threading.ManualResetEvent(false);

      public static Socket Connect(IPEndPoint remoteEndPoint, int timeoutMSec)
      {
            TimeoutObject.Reset();
            socketexception = null;

            Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socketClient.BeginConnect(remoteEndPoint, new AsyncCallback(CallBackMethod), socketClient);

            if (TimeoutObject.WaitOne(timeoutMSec, false))
            {
                if (IsConnectionSuccessful)
                  return socketClient;
                else
                  throw socketexception;
            }
            else
            {
                socketClient.Close();
                throw new TimeoutException("Connection TimeOut ");
            }

      }
      private static void CallBackMethod(IAsyncResult asyncresult)
      {
            try
            {
                IsConnectionSuccessful = false;
                Socket socketClient = asyncresult.AsyncState as Socket;

                if (socketClient != null)
                {
                  socketClient.EndConnect(asyncresult);
                  IsConnectionSuccessful = true;
                }
            }
            catch (Exception ex)
            {
                IsConnectionSuccessful = false;
                socketexception = ex;
            }
            finally
            {
                TimeoutObject.Set();
            }
      }
    }

xivisi 发表于 2018-8-3 16:21:48

本帖最后由 xivisi 于 2018-8-3 16:29 编辑

1、一次并发N个socket连接;
2、设定TCP连接超时短一点,反正局域网不影响

3、端口扫描工具了解一下,可以简单查看指定主机指定端口是否处于监听状态

leafstamen 发表于 2018-8-3 16:25:00

SUPER_CRJ 发表于 2018-8-3 15:51
好方法,但是有没有不用UDP的?现在尝试连接等待出错连接不上要几秒的时间。
而且一个问题:UDP能给TCP服 ...

udp不能发给tcp,需要你的tcp服务器也坚定udp数据,相当于是udp握手,tcp业务。

hyghyg1234 发表于 2018-8-3 16:29:29

网络中还有其他设备吗,如果没有采取ping的方式。

wye11083 发表于 2018-8-3 17:37:05

xivisi 发表于 2018-8-3 16:21
1、一次并发N个socket连接;
2、设定TCP连接超时短一点,反正局域网不影响



只有2才是可行的。要我就直接开满一个子网同时查,哪个返回就用哪个。

SUPER_CRJ 发表于 2018-8-6 09:15:45

longlong105 发表于 2018-8-3 16:10
TCP超时时间设置!
本class 来自网络,目前我正在使用!



已测试,非常好用,谢谢

sunny_82 发表于 2018-8-6 18:10:33

这种尝试的时间和资源开销大了点,其实,用组播方式来查询发布服务和申请,还可以有更多选择,比如均衡下多个服务器的负荷。
页: [1]
查看完整版本: C#如何快速的查找可用的TCP服务器