我目前正在研究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;
}
}
但是,当我切换到 ReceiveAsync(ArraySegment, SocketFlags) 方法时,效果很好。 tcpRecReserve 接收准确的数据。 我的问题是为什么会发生这种情况以及如何解决它。
你提到“团结”;这可能是一个 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)}'");
}
}