JAVA通过fserver_java – 通过Netty中的ServerBootstrap ChannelPipeline发送消息时出现UnsupportedOperationException...

在使用Netty 5.0时,作者在尝试通过ServerBootstrap从服务器向已连接的客户端发送消息时遇到了java.lang.UnsupportedOperationException。问题出现在`ch.writeAndFlush()`方法调用中。尽管客户端可以成功接收消息,但服务器端无法写回响应。讨论中提到,ServerBootstrap可能不支持直接从Pipeline外部发送消息,可能是设计为仅用于接收。代码示例展示了如何初始化ServerBootstrap和处理通道,并在遇到异常时打印错误信息。
摘要由CSDN通过智能技术生成

我正在使用Netty 5.0.

我有一个补充的客户端引导程序,我从netty github获取了SecureChatClient.java示例.

Wenn我从客户端bootstrap发送消息到它完全正常工作的服务器.当我尝试从服务器引导程序向客户端发送消息时(首先通过客户端成功启动连接/通道之后),我得到了一个java.lang.UnsupportedOperationException而没有任何进一步的信息.从服务器向客户端发送消息是通过上面的代码完成的.

是仅用于接收的serverbootstrap吗?

如上所示,serverbootstrap不能将消息写回客户端吗?我的意思是,消息可以通过ChannelHandler从套接字进入ChannelPipeline,但只有ChannelHandler应该将响应写回ChannelPipeline并退出套接字.因此,在ServerBootstrap中,用户并不意味着能够从Pipeline外部沿ChannelPipeline发送消息. (希望有道理)

或者我只是遗漏了什么?

我的代码如下:

// Ports.

int serverPort = 8080;

EventLoopGroup bossGroup = new NioEventLoopGroup();

EventLoopGroup workerGroup = new NioEventLoopGroup();

try {

ServerBootstrap b = new ServerBootstrap();

b.group(bossGroup, workerGroup)

.channel(NioServerSocketChannel.class)

.childHandler(new ChannelInitializer() {

@Override

public void initChannel(SocketChannel ch) throws Exception {

ch.pipeline().addLast("MyMessageHandler", new MyMessageHandler());

}

})

.option(ChannelOption.SO_BACKLOG, 128)

.childOption(ChannelOption.SO_KEEPALIVE, true);

// Bind and start to accept incoming connections.

ChannelFuture f = b.bind(serverPort).sync();

Channel ch = f.channel();

System.out.println("Server: Running!");

// Read commands from the stdin.

ChannelFuture lastWriteFuture = null;

BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

while(true)

{

String line = in.readLine();

if (line == null) break;

ByteBuf getOut = buffer(64);

getOut.writeBytes(line.getBytes());

// Sends the received line to the server.

lastWriteFuture = ch.writeAndFlush(getOut);

lastWriteFuture.addListener(new ChannelFutureListener() {

@Override

public void operationComplete(ChannelFuture cf) throws Exception {

if(cf.isSuccess()) {

System.out.println("CFListener: SUCCESS! YEAH! HELL! YEAH!");

} else {

System.out.println("CFListener: failure! FAILure! FAILURE!");

System.out.println(cf.cause());

}

}

});

}

// Wait until all messages are flushed before closing the channel.

if (lastWriteFuture != null) {

lastWriteFuture.sync();

}

// Wait until the server socket is closed.

// In this example, this does not happen, but you can do that to gracefully

// shut down your server.

f.channel().closeFuture().sync();

} catch (InterruptedException | UnsupportedOperationException e) {

e.printStackTrace();

} finally {

workerGroup.shutdownGracefully();

bossGroup.shutdownGracefully();

}

我的问题是我在调用ch.writeAndFlush时遇到以下异常:

java.lang.UnsupportedOperationException

at io.netty.channel.socket.nio.NioServerSocketChannel.filterOutboundMessage(NioServerSocketChannel.java:184)

at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:784)

at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1278)

at io.netty.channel.ChannelHandlerInvokerUtil.invokeWriteNow(ChannelHandlerInvokerUtil.java:158)

at io.netty.channel.DefaultChannelHandlerInvoker$WriteTask.run(DefaultChannelHandlerInvoker.java:440)

at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:328)

at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)

at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)

at io.netty.util.internal.chmv8.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1412)

at io.netty.util.internal.chmv8.ForkJoinTask.doExec(ForkJoinTask.java:280)

at io.netty.util.internal.chmv8.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:877)

at io.netty.util.internal.chmv8.ForkJoinPool.scan(ForkJoinPool.java:1706)

at io.netty.util.internal.chmv8.ForkJoinPool.runWorker(ForkJoinPool.java:1661)

at io.netty.util.internal.chmv8.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:126)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个示例代码,如下: ```delphi unit UMyUdpServer; interface uses Classes, IdGlobal, IdSocketHandle, IdUDPBase, IdUDPServer, SysUtils; type TMyUdpServer = class(TIdUDPServer) private FOnDataReceived: TNotifyEvent; protected procedure DoUDPRead(AData: TIdBytes; ABinding: TIdSocketHandle); override; public property OnDataReceived: TNotifyEvent read FOnDataReceived write FOnDataReceived; end; implementation procedure TMyUdpServer.DoUDPRead(AData: TIdBytes; ABinding: TIdSocketHandle); var Stream: TMemoryStream; FileName: string; begin Stream := TMemoryStream.Create; try Stream.WriteBuffer(AData[0], Length(AData)); Stream.Position := 0; // 在这里可以对Stream进行处理 if Assigned(FOnDataReceived) then FOnDataReceived(Self); // 将Stream保存到文件 FileName := FormatDateTime('yyyymmddhhnnsszzz', Now) + '.dat'; Stream.SaveToFile(FileName); finally Stream.Free; end; end; end. ``` 这是一个继承自`TIdUDPServer`的自定义组件,它重写了`DoUDPRead`方法,在方法内部可以对接收到的数据进行处理,并将数据保存到文件。同,这个组件还增加了一个`OnDataReceived`事件,可以在外部接收到数据后进行一些额外的操作。 在使用过程,您可以将这个组件放在一个线程,然后启动线程即可。 ```delphi unit UMyThread; interface uses Classes, UMyUdpServer; type TMyThread = class(TThread) private FServer: TMyUdpServer; protected procedure Execute; override; procedure DoDataReceived(Sender: TObject); public constructor Create; destructor Destroy; override; end; implementation constructor TMyThread.Create; begin FServer := TMyUdpServer.Create(nil); FServer.DefaultPort := 12345; FServer.OnDataReceived := DoDataReceived; FServer.Active := True; inherited Create(False); end; destructor TMyThread.Destroy; begin FServer.Free; inherited; end; procedure TMyThread.Execute; begin while not Terminated do begin // do something end; end; procedure TMyThread.DoDataReceived(Sender: TObject); begin // do something end; end. ``` 这个线程启动了一个`TMyUdpServer`,并将其绑定到了本地的12345端口。同,它还实现了`DoDataReceived`方法,在这个方法可以对接收到的数据进行处理。您可以在这个方法调用其他的处理函数,比如将数据存储到数据库等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值