0

我有以下代码可以与多个端点建立 TCP 套接字连接:

    private async void button1_Click(object sender, EventArgs e)
    {
        var listofIps = new List<string> { "192.168.168.193", "192.168.168.221" };
        foreach (var ip in listofIps)
        {
            IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ip), 4001);
            Socket client = new Socket(AddressFamily.InterNetwork,
                                       SocketType.Stream, ProtocolType.Tcp);
            sockets.Add(client);
            await client.ConnectTaskAsync(remoteEP);
            await ReadAsync(client);
        }
    }

    async Task ReadAsync(Socket s)
    {            
        var args = new SocketAsyncEventArgs();
        args.SetBuffer(new byte[1024], 0, 1024);

        var awaitable = new SocketAwaitable(args);

        while (true)
        {
            await s.ReceiveAsync(awaitable);
            int bytesRead = args.BytesTransferred;
            if (bytesRead <= 0) break;

            var data = new ArraySegment<byte>(args.Buffer, 0, bytesRead);
            AppendLog("RX: " + data.DumpHex());
        }
    }

    public static string DumpHex(this ArraySegment<byte> data)
    {
        return string.Join(" ", data.Select(b => b.ToString("X2")));
    }

    public static Task ConnectTaskAsync(this Socket socket, EndPoint endpoint)
    {            
        return Task.Factory.FromAsync(socket.BeginConnect, socket.EndConnect, endpoint, null);
    }

但是,由于等待 ReadAsync,循环不会迭代传递第一个 IP 地址。

Qn 1)我如何修改此代码,以便它遍历我的整个 IP 列表,而无需“等待”完全接收数据。我await要从 await 中删除关键字ReadAsync(client)吗?
Qn 2) 我如何修改此代码以使其一次连接到所有 IP。(这可能吗?)

4

1 回答 1

4

如何修改此代码,使其遍历我的整个 IP 列表

您的代码迭代整个列表。但它只有在接收到来自第一个地址的所有数据后才会到达第二个地址。

如何修改此代码以使其一次连接到所有 IP。

如果将单个地址的代码封装到单独的async方法中,则可以先为每个地址调用它,然后再调用await所有返回Task的 s。或者你可以使用 LINQ:

private async void button1_Click(object sender, EventArgs e)
{
    var listOfIps = new List<string> { "192.168.168.193", "192.168.168.221" };
    await Task.WhenAll(listOfIps.Select(ip => ReadFromAddress(ip)));
}

private async Task ReadFromAddress(string address)
{
    IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ip), 4001);
    Socket client = new Socket(AddressFamily.InterNetwork,
                               SocketType.Stream, ProtocolType.Tcp);
    sockets.Add(client);
    await client.ConnectTaskAsync(remoteEP);
    await ReadAsync(client);
}
于 2013-07-05T12:53:52.097 回答