【问题标题】:Resend data to socket endpoint if there's no response after a certain time如果在一定时间后没有响应,则将数据重新发送到套接字端点
【发布时间】:2013-07-06 03:23:36
【问题描述】:

我有以下 TAP 方法来读取和写入数据到我的套接字端点

    private async Task ReadFromAddress(string address)
    {
        IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(address), 4001);
        Socket client = new Socket(AddressFamily.InterNetwork,
                                   SocketType.Stream, ProtocolType.Tcp);
        sockets.Add(client);
        await client.ConnectTaskAsync(remoteEP);
        await ReadAsync(client);
    }

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

        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 Task<int> SendAsync(this Socket socket, byte[] buffer, int offset, int count)
    {
        return Task.Factory.FromAsync<int>(
                       socket.BeginSend(buffer, offset, count, SocketFlags.None, null, socket),
                 socket.EndSend);            
    }
    public static Task<int> SendTaskAsync(this Socket socket, byte[] buffer, int offset, int size, SocketFlags flags)
    {
        AsyncCallback nullOp = (i) => { };
        IAsyncResult result = socket.BeginSend(buffer, offset, size, flags, nullOp, socket);
        // Use overload that takes an IAsyncResult directly
        return Task.Factory.FromAsync<int>(result, socket.EndSend);
    }

这就是我连接到我的 IP 地址列表的方式

    private async void button1_Click(object sender, EventArgs e)
    {
        var listOfIps = new List<string> { "192.168.168.199", "192.168.168.221" };

        await Task.WhenAll(listOfIps.Select(ip => ReadFromAddress(ip)));
    }

每次我使用 WriteAsync 发送一些数据时,我都应该几乎立即获得一些数据。如果可能的话,我应该如何以 TAP 化的方式扩展我的代码,这样如果我在 3 秒内没有从该特定套接字返回任何回复。我将再次重新发送数据?

这是我将数据写入特定套接字的方式:

var socket = sockets[i];
var returnMessage =new byte[2];
returnMessage[0] = 0x01;
returnMessage[1] = 0x02;
await socket.WriteAsync(returnMessage);

【问题讨论】:

    标签: c# sockets task-parallel-library async-await


    【解决方案1】:

    首先,我建议您不要混合使用不同的异步系统。我建议用 TAP 方法替换 SocketAsyncEventArgs

    要按照您的建议设置超时,您需要创建另一个图层。您当前的代码处理低级读取和写入;您需要更高的消息级抽象。

    【讨论】:

    • TAP 版本的 SocketAsyncEventArgs 会是什么样子?代码 sn-p 将有助于我如何在另一层中这样做
    • 我的意思是始终如一地使用 FromAsync 包装器,就像您为 Connect 所做的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 1970-01-01
    相关资源
    最近更新 更多