首页 > 解决方案 > 是否可以从客户端机器测试特定的 IP 地址和端口?

问题描述

我编写了以下类来连接客户端(到服务器):

public class ClientClass
{
    public string Host { get; set; }
    public int Port { get; set; }

    public TcpClient Tcp { get; private set; }
    private BinaryReader reader;
    private BinaryWriter writer;

    /// <summary>
    /// Creates a clienbt at the Client-end. 
    /// This requires Host and Post property to be set.
    /// </summary>
    public ClientClass()
    {

    }

    /// <summary>
    /// Creates a client at the Client-end.
    /// </summary>
    /// <param name="host"></param>
    /// <param name="port"></param>
    public ClientClass(string host, int port)
    {
        Host = host;
        Port = port;
    }

    /// <summary>
    /// creates a proxy-client at the Server-end.
    /// </summary>
    /// <param name="listener"></param>
    public ClientClass(TcpListener listener)
    {
        Tcp = listener.AcceptTcpClient();

        Host = ((IPEndPoint)Tcp.Client.RemoteEndPoint).Address.ToString();
        Port = ((IPEndPoint)Tcp.Client.LocalEndPoint).Port;

        NetworkStream stream = Tcp.GetStream();
        reader = new BinaryReader(stream);
        writer = new BinaryWriter(stream);
    }

    /// <summary>
    /// Connects the client to the server.
    /// </summary>
    /// <returns></returns>
    public bool Connect()
    {
        bool is_connected = IsConnected();

        if (!is_connected)
        {
            Tcp = new TcpClient(Host, Port);

            NetworkStream stream = Tcp.GetStream();
            reader = new BinaryReader(stream);
            writer = new BinaryWriter(stream);

            return true;
        }

        if (is_connected)
        {
            return true;
        }

        return false;
    }

    public bool IsConnected()
    {
        if (Tcp == null)
        {
            return false;
        }
        else
        {
            Socket s = Tcp.Client;

            bool part1 = s.Poll(1000, SelectMode.SelectRead);
            bool part2 = (s.Available == 0);
            if ((part1 && part2) || !s.Connected)
                return false;
            else
                return true;
        }
    }

    public void Write(string str)
    {
        if (IsConnected())
        {
            byte[] strBytes = Encoding.UTF8.GetBytes(str);
            byte[] lenBytes = BitConverter.GetBytes(strBytes.Length);
            Array.Reverse(lenBytes);
            writer.Write(lenBytes);
            writer.Write(strBytes);
            writer.Flush();
        }
        else
        {
            throw new Exception("Client  is not connected!");
        }
    }

    public string Read()
    {
        if (IsConnected())
        {
            byte[] lenBytes = reader.ReadBytes(4);
            Array.Reverse(lenBytes);
            int len = BitConverter.ToInt32(lenBytes, 0);
            byte[] bytes = reader.ReadBytes(len);
            string str = Encoding.UTF8.GetString(bytes);

            return str;
        }
        else
        {
            throw new Exception("Client  is not connected!");
        }
    } 

    public bool Close()
    {
        if (IsConnected())
        {
            if (Tcp != null)
            {
                Tcp.Close();
                Tcp = null;

                return true;
            }
        }

        return false;
    }
}

假设,在连接到服务器之前,我想测试服务器是否在 IP 地址x.x.x.x和端口上处于活动状态y

可能吗?

标签: c#tcpclient-server

解决方案


似乎无法设置连接超时,但您可以像这样解决问题:

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

TcpClient socket = new TcpClient();

if (TestWithTimeout(socket,"1.2.3.4",80,1))
{
//  ....
}   


 bool TestWithTimeout( Socket/TcpClient socket = new TcpClient(); socket, string host, int port, int timeout)
{
    Task result = socket.ConnectAsync(host, port);
    Task.WaitAny(new[] { result }, timeout);
    return socket.Connected;
}

推荐阅读