当前位置: 首页 > 知识库问答 >
问题:

在 netty 套接字编程中使用外部调用发送消息

柯振濂
2023-03-14

我是套接字编程和Netty框架的新手。我试图修改Echo服务器的例子,这样就不会一收到消息就从客户端发送消息,而是来自另一个线程的调用会触发客户端向服务器发送消息。

问题是,服务器不会收到消息,除非客户端从读取通道或消息接收或通道活动发送消息,这些消息是使用参数指定服务器的位置(通道处理程序上下文)。我无法设法找到一种方法来保存服务器通道并在以后重复发送消息。

这是我的客户处理程序代码;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class EchoClientHandler extends ChannelHandlerAdapter {

    ChannelHandlerContext server;

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        this.server = ctx; 
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
       // ctx.write(msg);  //not
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
       //ctx.flush();
    }
    public void externalcall(String msg) throws Exception {
        if(server!=null){
            server.writeAndFlush("[" + "] " + msg + '\n');
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        ctx.close();
    }
}

当Client创建处理程序时,它还创建了一个带有“SourceGenerator”对象的线程,该对象将处理程序作为参数获取,以便调用externalcall()方法。

    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioSocketChannel;

    /**
     * Sends one message when a connection is open and echoes back any received
     * data to the server.  Simply put, the echo client initiates the ping-pong
     * traffic between the echo client and server by sending the first message to
     * the server.
     */
    public class EchoClient {

        private final String host;
        private final int port;

        public EchoClient(String host, int port, int firstMessageSize) {
            this.host = host;
            this.port = port;
        }
        public void run() throws Exception {
            // Configure the client.
            EventLoopGroup group = new NioEventLoopGroup();
            final EchoClientHandler x = new EchoClientHandler();
            SourceGenerator sg = new SourceGenerator(x);
            new Thread(sg).start();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group)
                 .channel(NioSocketChannel.class)
                 .option(ChannelOption.TCP_NODELAY, true)
                 .handler(new ChannelInitializer<SocketChannel>() {
                     @Override
                     public void initChannel(SocketChannel ch) throws Exception {
                         ch.pipeline().addLast(x);
                     }
                 });

                // Start the client.
                ChannelFuture f = b.connect(host, port).sync();

                // Wait until the connection is closed.
                f.channel().closeFuture().sync();
            } finally {
                // Shut down the event loop to terminate all threads.
                group.shutdownGracefully();
            }
        }

        public static void main(String[] args) throws Exception {
            // Print usage if no argument is specified.
            if (args.length < 2 || args.length > 3) {
                System.err.println(
                        "Usage: " + EchoClient.class.getSimpleName() +
                        " <host> <port> [<first message size>]");
                return;
            }
            // Parse options.
            final String host = args[0];
            final int port = Integer.parseInt(args[1]);
            final int firstMessageSize;
            if (args.length == 3) {
                firstMessageSize = Integer.parseInt(args[2]);
            } else {
                firstMessageSize = 256;
            }

            new EchoClient(host, port, firstMessageSize).run();
        }
    }

和源生成器类;

java prettyprint-override">public class SourceGenerator implements Runnable {
    public String dat;
    public EchoClientHandler asd;
    public SourceGenerator(EchoClientHandler x) {
        asd = x;
        System.out.println("initialized source generator");
        dat = "";
    }

    @Override
    public void run() {
        try{
            while(true){
                Thread.sleep(2000);
                dat += "a"; 
                asd.externalcall(dat);
                System.out.print("ha!");
            }
        }catch(Exception e){
            e.printStackTrace();

        }
    }
}

提前感谢!

共有1个答案

楚望
2023-03-14

如果要编写String,则需要在ChannelPipeline中具有

否则,您只能发送< code>ByteBuf实例

 类似资料:
  • 问题内容: 我想使用能够发送和接收文件的套接字和C / C ++语言实现在Linux上运行的客户端-服务器体系结构。有没有可以简化此任务的库?有人可以举个例子吗? 问题答案: 最可移植的解决方案是读取文件,然后以循环方式将数据写到套接字中(同样,接收文件时也采用另一种方法)。您可以在该缓冲区中分配一个缓冲区,并从该缓冲区中将其分配到您的套接字中(您也可以使用和,这是套接字特定的写入和读取数据的方式

  • 我编写了一个基于Netty4的REST服务器。客户端处理程序如下所示。 netty提供的msg中的bytebuffer容量各不相同。当客户端消息大于缓冲区时,消息将被拆分。我发现每个片段都调用channelRead和ChannelReadComplete。我通常看到的是ByteBuf在512左右,message在600左右。对于前512个字节,我得到一个channelRead,然后是一个Chann

  • 我制作了一个简单的服务器程序,可以同时从4个不同的客户端接收数据。现在我想用AES-128加密发送一些数据,但应该在服务器端解码。以下是我的服务器代码: 我从客户端发送这样的数据 我应该如何修改我的客户端代码和服务器代码,以便在其中包含AES-128加密。。请在这方面帮助我。

  • 我正在尝试创建一个仅在共享内存中具有文件的小文件服务器。客户端应该向服务器发送命令,如 CREATE、DELETE 等。但是,我还没有到那个阶段。 我已经准备了一个服务器和一个客户端。服务器接受套接字,并为每个客户端连接创建一个新线程(要求)。 当我启动客户端时,我可以成功连接到服务器并发送将被接收的消息。但是,这只能工作一次。发送我的命令后,服务器将不会收到任何其他命令。 我尝试使用换行符捕获消

  • 以前的代码是用c语言编写的,使用的是这样的代码: 这段代码可以工作,但我必须使用Netty在java中重新实现它。 在tcp中使用netty不是问题,但是用netty回复客户机对我来说是个问题,如果我想在通道上写,它失败了,出现了。 也许这与netty上的这个问题有关,但我不知道如何在代码中再现c行为。 如何回复客户? 多谢了。 编码器代码:

  • 我对Android系统是新手。我有一个客户端类,我的主要活动引用。client类将客户端套接字连接到充当服务器的外部设备,但是它从不将我试图发送的消息发送到服务器。我知道这不是连接,因为在创建套接字时,我将setKeepAlive()设置为true,当我试图发送消息时不会引发异常,socket.isconnected()返回true,如果我试图在发送消息之前连接套接字,它会引发“已经连接”的异常。