【发布时间】:2023-04-02 00:55:01
【问题描述】:
我正在试验 DotNetty 在企业应用程序中使用它。
在我的基本示例中,当我在 CLIENT 中使用 DotNetty 的 API 调用服务器时,一切都很好,但是当我使用纯 C# TcpClient 时,只有 ChannelReadComplete 会触发,而 ServerHandler 中不会触发 ChannelRead。
ServerHandler:
public class EchoServerHandler : ChannelHandlerAdapter
{
public override void ChannelRead(IChannelHandlerContext context, object message)
{
var buffer = message as IByteBuffer;
if (buffer != null)
{
Console.WriteLine("Received from client: " + buffer.ToString(Encoding.UTF8));
}
context.WriteAsync(message);
}
public override void ChannelReadComplete(IChannelHandlerContext context) => context.Flush();
public override void ExceptionCaught(IChannelHandlerContext context, Exception exception)
{
Console.WriteLine("Exception: " + exception);
context.CloseAsync();
}
}
}
客户:
TcpClient client = new TcpClient();
client.Connect("127.0.0.1", 8583);
var data = Encoding.UTF8.GetBytes("Hello world");
Stream stm = client.GetStream();
stm.Write(data, 0, data.Length);
byte[] readBytes = new byte[100];
stm.Read(readBytes, 0, readBytes.Length);
stm.Close();
client.Close();
有什么想法吗?
【问题讨论】:
-
您不能将 127.0.0.1 与作为环回地址的连接方法一起使用。您必须使用真实的 IP 地址。服务端 TCPListener 使用环回地址监听,但在 Net 库中连接 127.0.0.1 会导致异常。
-
@jdweng 好吧,我不是 TCP/IP 专家,但相同的配置适用于 DotNetty 客户端项目。无论如何,我将IP更改为实际IP,并且没有任何异议。 ServerHandler 中仍然只有 ChannelReadComplete 会触发。
-
客户端可以有两个定义。一个在应用程序级别,您有一个连接到服务器的客户端。另一个定义是在客户端和服务器应用程序都有客户端套接字的套接字级别。我认为您在上面发布的客户端是服务器上的客户端。然后你应该使用 TcpListener(不是 TcpClient),就像下面的网站一样:msdn.microsoft.com/en-us/library/…。在应用程序客户端连接之前不会发生通道读取。您的客户端应用程序在哪里?
-
@jdweng 不,这段代码是客户端应用程序!服务器正在运行,客户端应用程序能够连接到端口并发送数据。甚至服务器也会对请求做出反应,但不是 ChannelRead,而是只有 ChannelReadComplete fiers。
-
TCP 连接是一个流,当流关闭时会发生流结束 TCP 将消息拆分为数据报,数据报的最大大小约为 1500 字节。我认为 DotNettys ChannelReadCompletes 在连接关闭时触发(不确定)并且在连接被应用程序关闭或出现错误时发生。接收到每个数据报时应触发读取。如果在收到数据报后立即关闭连接,您可能只会得到 ChannelReadComplete (好猜测)。请参阅以下帖子:stackoverflow.com/questions/23083868/…