通过 ReceiveAsync(Memory<Byte>, SocketFlags, CancellationToken) 方法不接收任何内容

问题描述 投票:0回答:1

我目前正在研究TCP接收编程。问题是当我使用 int reclen = ReceiveAsync(Memory, SocketFlags, CancellationToken) 方法时,reclen > 0 但我在内存中什么也没收到(tcpRecReserve)。

    public async Task BeginTcpRecieve()
    {
        try
        {   
            //ArraySegment<byte> bytes = new ArraySegment<byte>(tcpRecReserve,catchNum, tcpRecReserve.Length - catchNum);
            Memory<byte> memory = new Memory<byte>(tcpRecReserve, catchNum, tcpRecReserve.Length - catchNum);
            int reclen = await tcpSocket.ReceiveAsync(memory, SocketFlags.None);
            HandleReceive(reclen);
            await BeginTcpRecieve();
        }
        catch (SocketException e)
        {
            print(e.ErrorCode + "/" + e.Message); 
            isConnected= false;
        }
        
    }

Debugging Image1

但是,当我切换到 ReceiveAsync(ArraySegment, SocketFlags) 方法时,效果很好。 tcpRecReserve 接收准确的数据。 Debugging Image2 我的问题是为什么会发生这种情况以及如何解决它。

c#
1个回答
0
投票

你提到“团结”;这可能是一个 Unity 错误,或者可能是您未显示的代码中的错误,但是:这是代码的稍微修改版本(只是更改为使用循环而不是递归)工作正常;输出是:

Received: '+PONG
'

这是 RESP

PING
消息的预期响应;代码:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

static class Program
{
    async static Task Main()
    {
        var client = new Client();
        // connect to a local Garnet server (same API as Redis)
        await client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, 3278));
        // note this usage is convenient, but not efficient
        await client.SendAsync("*1\r\n$4\r\nPING\r\n"u8.ToArray());
        await client.BeginTcpRecieve();
    }
}

internal sealed class Client
{
    private Socket tcpSocket;
    private byte[] tcpRecReserve = new byte[1024];
    int catchNum;
    private bool isConnected;

    public async Task ConnectAsync(EndPoint endPoint)
    {
        tcpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        await tcpSocket.ConnectAsync(endPoint);
        isConnected = true;
    }

    public Task SendAsync(ReadOnlyMemory<byte> frame)
        =>  tcpSocket.SendAsync(frame).AsTask();

    public async Task BeginTcpRecieve()
    {
        try
        {
            while (true)
            {
                //ArraySegment<byte> bytes = new ArraySegment<byte>(tcpRecReserve,catchNum, tcpRecReserve.Length - catchNum);
                Memory<byte> memory = new Memory<byte>(tcpRecReserve, catchNum, tcpRecReserve.Length - catchNum);
                int reclen = await tcpSocket.ReceiveAsync(memory, SocketFlags.None);
                if (reclen <= 0) break; // EOF
                HandleReceive(reclen);
            }
        }
        catch (SocketException e)
        {
            print(e.ErrorCode + "/" + e.Message);
            isConnected = false;
        }

    }

    private static void print(string v) => Console.WriteLine(v);

    private void HandleReceive(int reclen)
    {
        Console.WriteLine($"Received: '{Encoding.ASCII.GetString(tcpRecReserve, 0, reclen)}'");
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.