使用netty进行客户端和传统的socket进行通讯

一,服务端以下方式读取数据,则发送的数据必须以换行符/n结尾

String msg = reader.readLine()

1.我们在客户端只要使用传统的客户端编写方式即可

package com.netty.study.nettystart.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.oio.OioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.channel.socket.oio.OioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

public class NettyClient {
    public static void main(String[] args) {
        EventLoopGroup group = new OioEventLoopGroup();

        try {
            ChannelFuture nettyclient_连接陈工 = new Bootstrap()
                    .group(group)
                    .channel(OioSocketChannel.class)
                    .remoteAddress(new InetSocketAddress("127.0.0.1",9746))
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel nioSocketChannel) throws Exception {
//                            nioSocketChannel.pipeline().addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
                            nioSocketChannel.pipeline().addLast(new SimpleChannelInboundHandler<ByteBuf>() {
                                @Override
                                public void channelActive(ChannelHandlerContext ctx) throws Exception {
                                    String message = "Hello Server\n";
                                    ByteBuf buffer = Unpooled.copiedBuffer(message.getBytes());
                                    ctx.writeAndFlush(buffer);
                                }

                                @Override
                                public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
                                    cause.printStackTrace();
                                    ctx.channel().close();
                                }

                                @Override
                                protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
                                    System.out.println(byteBuf.toString(Charset.defaultCharset()));

                                }

                                @Override
                                public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
                                    super.channelRegistered(ctx);
                                }
                            });
                        }
                    }).connect().sync();
            nettyclient_连接陈工.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
                group.shutdownGracefully();
        }
    }
}

2.服务端代码

package com.netty.study.nettystart.server;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class SimpleSocketServer {
    private static final int PORT = 9746;

    public static void main(String[] args) throws IOException {
        final String QUIT = "quit";
        final int DEFAULT_PORT = 9746;
        ServerSocket serverSocket = null;
        BufferedReader reader = null;
        BufferedWriter writer = null;

        try {
            // 绑定监听端口
            serverSocket = new ServerSocket(DEFAULT_PORT);
            System.out.println("启动服务器,监听服务器本地端口" + DEFAULT_PORT);

            while (true) {
                // 等待客户端连接
                Socket socket = serverSocket.accept();
                System.out.println("客户端["+socket.getInetAddress()+":"+ socket.getPort() + "]已连接");

                InputStream inputStream = socket.getInputStream();


                reader = new BufferedReader(
                        new InputStreamReader(inputStream)
                );

                writer = new BufferedWriter(
                        new OutputStreamWriter(socket.getOutputStream())
                );


                String msg = reader.readLine();
                while (msg != null) {
                    // 读取客户端发送的消息
                    System.out.println("客户端["+socket.getInetAddress()+":"+ socket.getPort() + "]: " + msg);

                    // 回复客户发送的消息
                    writer.write("服务器已收到: " + msg + "\n");
                    //防止消息遗留到本地缓冲区,保证马上发送出去
                    writer.flush();

                    // 查看客户端是否退出
                    if (QUIT.equalsIgnoreCase(msg)) {
                        System.out.println("客户端["+socket.getInetAddress()+":"+ socket.getPort() + "]已断开连接");
                        break;
                    }
                }
//                System.out.println(decodedData+"_----------------------------------");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                serverSocket.close();
                reader.close();
                writer.close();
                System.out.println("关闭serverSocket");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
}

 二,服务端直接以字节数组接收

1.客户端代码和上边一样,唯一的区别就是,不需要固定结尾的/n了,随便发送即可

2.服务端代码:

package com.netty.study.nettystart.server;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

public class SimpleSocketServer {
    private static final int PORT = 9746;

    public static void main(String[] args) throws IOException {
        final String QUIT = "quit";
        final int DEFAULT_PORT = 9746;
        ServerSocket serverSocket = null;
        BufferedReader reader = null;
        BufferedWriter writer = null;

        try {
            // 绑定监听端口
            serverSocket = new ServerSocket(DEFAULT_PORT);
            System.out.println("启动服务器,监听服务器本地端口" + DEFAULT_PORT);

            while (true) {
                // 等待客户端连接
                Socket socket = serverSocket.accept();
                System.out.println("客户端["+socket.getInetAddress()+":"+ socket.getPort() + "]已连接");
                
                InputStream inputStream = socket.getInputStream();
                byte[] buffer = new byte[1024];
                int bytesRead = inputStream.read(buffer); // 读取字节数据
                byte[] receivedData = Arrays.copyOf(buffer, bytesRead); // 接收到的字节数据
// 解码操作,例如将字节数组转换为字符串
                String decodedData = new String(receivedData, StandardCharsets.UTF_8);


               
                System.out.println("消息:"+decodedData+"_----------------------------------");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                serverSocket.close();
                reader.close();
                writer.close();
                System.out.println("关闭serverSocket");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Netty是一款基于NIO的网络通讯框架,它提供了高性能、高可靠性的网络编程能力,因此可以用来实现即时通讯。以下是一个简单的使用Netty实现即时通讯的示例: 1. 创建一个Netty的Server和Client ```java // Server EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ServerHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); // 绑定口,开始接收进来的连接 ChannelFuture f = b.bind(port).sync(); // 等待服务器 socket 关闭 。 // 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。 f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } // Client EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new ClientHandler()); } }); // 连接服务 ChannelFuture f = b.connect(host, port).sync(); // 等待连接关闭 f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } ``` 2. 编写ServerHandler和ClientHandler ```java // ServerHandler public class ServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // 处理客户发送过来的消息 ByteBuf in = (ByteBuf) msg; try { System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8)); // 将消息返回给客户 ctx.write(in); ctx.flush(); } finally { ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 当出现异常时关闭连接 cause.printStackTrace(); ctx.close(); } } // ClientHandler public class ClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelActive(ChannelHandlerContext ctx) { // 发送消息给服务 ctx.writeAndFlush(Unpooled.copiedBuffer("Hello Server", CharsetUtil.UTF_8)); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // 处理服务返回的消息 ByteBuf in = (ByteBuf) msg; try { System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8)); } finally { ReferenceCountUtil.release(msg); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 当出现异常时关闭连接 cause.printStackTrace(); ctx.close(); } } ``` 这样,我们就可以用Netty实现简单的即时通讯了。当然,实际应用中还需要考虑更多的因素,例如协议的定义和解析、消息的组装和拆解等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EntyIU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值