使用超时实现异步tcp连接

时间:2017-11-13 20:12:22

标签: c# sockets asynchronous

我得到一个例外:

"An unhandled exception of type 'System.NotSupportedException' occurred in 
 System.dll

 Additional information: This protocol version is not supported."

当我运行以下代码时。我正在尝试使用超时实现异步tcp连接。

我已经看过并读过几个堆栈溢出示例,一些使用TcpClient,一些使用Socket。我认为前者包裹后者并且更新。我正在尝试使用TcpClient.BeginConnect

该文档未将NotSupported列为此方法可以抛出的异常类型之一。如何找出问题所在?

public class Client
{
    private string m_host;
    private uint m_port;
    private uint m_timeoutMilliseconds;
    private TcpClient m_client;

    public Client(string host, uint port, uint timeoutMilliseconds)
    {
        m_host = host;
        m_port = port;
        m_timeoutMilliseconds = timeoutMilliseconds;
        m_client = new TcpClient();
    }

    public bool Connect()
    {
        IPHostEntry hostInfo = Dns.GetHostEntry(m_host);
        IPAddress ipAddress = hostInfo.AddressList[0];
        IPEndPoint endpoint = new IPEndPoint(ipAddress, (int)m_port);

        IAsyncResult result = m_client.BeginConnect(ipAddress, (int)m_port, new AsyncCallback(OnConnect), m_client);
        result.AsyncWaitHandle.WaitOne((int)m_timeoutMilliseconds, true);

        // SNIP

        return true;
    }

    public void Disconnect()
    {
        throw new NotImplementedException();
    }

    public void MakeRequest(string symbol)
    {
        throw new NotImplementedException();
    }


    private static void OnConnect(IAsyncResult asyncResult)
    {
        Socket socket = (Socket)asyncResult.AsyncState;
        socket.EndConnect(asyncResult);

        Console.WriteLine("Socket connected to {0}"
                        , socket.RemoteEndPoint.ToString());

    }
}

class Program
{
    static void Main(string[] args)
    {
        Client client = new Integration.Client("127.0.0.1", 24001, 360000);
        client.Connect();
    }
}

2 个答案:

答案 0 :(得分:1)

默认情况下,Dim Column, Row As Integer 'used Sheets().Input(Row, Column).Value to insert strings Open strFilePath For Input Access Read As #1 Do Until EOF(1) Line Input #1, strLine strLine = Split(strLine, vbLf)(1) arr = Split(strLine, ",") For Column = 1 to 8 'insert stuff Next Column Row = Row + 1 Loop 假设您使用的是IPv4地址。有constructor overload允许您指定要使用的地址系列,但这意味着在完成dns查找后构建它:

CR

或者您可以在TcpClient中找到IPv4地址并连接到该地址 - 这就是BeginConnect(string host, ...)重载对您的影响(除非您在构造函数中指定了IPv6)。

我不知道为什么他们不只是从你传递的m_client = new TcpClient(ipAddress.AddressFamily); IAsyncResult result = m_client.BeginConnect(ipAddress, (int)m_port, new AsyncCallback(OnConnect), m_client); 中取出hostInfo.AddressList,也许是因为在AddressFamily中创建了基础IPAddress构造函数。我也很惊讶在Socket的{​​{3}}中看到以下内容:

TcpClient

我不明白这个评论,但显然有人在选择默认值时确实考虑过IPv6。

答案 1 :(得分:0)

如果您只是在IP4本地地址之后尝试此

using System.Linq;

IPAddress ipAddress = Dns.GetHostEntry(m_host).AddressList.FirstOrDefault(x => x.IsIPv6LinkLocal == false);

我刚尝试了你的例子并遇到了同样的错误,上面似乎有效。