简体   繁体   English

Netty 4.0客户端/服务器在连接时冻结

[英]Netty 4.0 Client/Server Freezes on Connection

Well i was working ok with Netty 3 but i wanted to work with Netty 4, i converted the code and got all of this below, im not sure if its a server issue and client issue in the code because it doesnt tell me, not even the source of the error, i also tried sending no data to the server and it still did it, i can not interact with the client but from tests it is making the application take up more ram very slowly and i am only sending strings that are not even 40 chars long 好吧,我可以与Netty 3一起正常工作,但是我想与Netty 4一起工作,所以我转换了代码并在下面得到了所有这些信息,我不确定代码中是否是服务器问题和客户端问题,因为它没有告诉我,甚至没有错误的根源,我也尝试不向服务器发送任何数据,但它仍然做到了,我无法与客户端进行交互,但是从测试中来看,它使应用程序占用的内存非常缓慢,并且我仅发送了甚至不到40个字符

MecaCoreConnector (Client): MecaCoreConnector(客户端):

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
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;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import main.java.net.meca.thecheatgamer1.CryptionUtils;
import main.java.net.mecalib.logger.Logger;

public class MecaCoreConnector {

    private static CryptionUtils cryption = new CryptionUtils();

    protected static UserAuthenticationData userdata;

    private ChannelFuture ch;

    private final static String host = "secret";
    private final static int port = secret;

    private static MecaCoreConnector MecaConnection;

    public MecaCoreConnector() {
        MecaConnection = this;
    }

    public void init() throws InterruptedException {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();

            bootstrap.group(workerGroup);
            bootstrap.channel(NioSocketChannel.class);
            bootstrap.option(ChannelOption.SO_KEEPALIVE, true);

            bootstrap.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel channel) throws Exception {
                    channel.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
                    channel.pipeline().addLast("decoder", new StringDecoder());
                    channel.pipeline().addLast("encoder", new StringEncoder());
                    channel.pipeline().addLast("handler", new MecaCoreConnectorAdapter());
                }
            });
            ch = bootstrap.connect(host, port).sync();
            ch.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }

    public void login(String username, String password) throws Exception {
        ch.channel().write("Username:" + username + " Password:" + cryption.getEncrpytedString(password) + "\r\n");
        ch.channel().flush();
    }

    public void fetchAdvertisments() {
        //channel.write("request: advertisments");
    }

    public static MecaCoreConnector getMecaConnection() {
        return MecaConnection;
    }

    public static UserAuthenticationData getUserData() {
        return userdata;
    }
}

MecaCoreConnectionAdapter (Client): MecaCoreConnectionAdapter(客户端):

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.awt.Image;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.UUID;

import javax.imageio.ImageIO;

import main.java.net.meca.launcher.gui.LoginClient;
import main.java.net.meca.launcher.gui.panel.home.Advertisment;
import main.java.net.mecalib.logger.Logger;

public class MecaCoreConnectorAdapter extends ChannelInboundHandlerAdapter {

    public static MecaCoreConnectorAdapter instance;

    public enum Command {
        // Creation
        createFile, createFolder,

        // Deletion
        removeFile, removeFolder,

        // Window Instructors
        closeWindow, openWindow, sendAlert, sendMessage,

        // User Instructors
        createUser
    }

    public enum LoginDataType {
        NumericID, UUID, GameUUID, AvatarLink, Rank
    }

    public enum DataType {
        // Common Types
        file, folder, zipExtraction,

        // Advertisments
        downloadAdvertisment, deleteAdvertisment
    }

    /*
     * Stored Data
     */

    public static Advertisment[] ads;
    public String imageURLs;
    public String imageLinks;
    public String viewChances;

    /*
     * 
     */

    public MecaCoreConnectorAdapter() {
        instance = this;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object e) {
        if (String.valueOf(e).contains("createUser")) {
            MecaCoreConnector.getMecaConnection().userdata = new UserAuthenticationData();
        } else if (String.valueOf(e).contains("NumericID")) {
            MecaCoreConnector.getMecaConnection().getUserData().setNumericID(Integer.parseInt(String.valueOf(e).replace("NumericID ", "")));
        } else if (String.valueOf(e).contains("UUID")) {
            MecaCoreConnector.getMecaConnection().getUserData().setUUID(UUID.randomUUID()/*UUID.fromString(String.valueOf(e.getMessage()).replace("UUID: ", ""))*/);
        } else if (String.valueOf(e).contains("GameUUIDs")) {
            // TODO: Make UUID parser for this
            MecaCoreConnector.getMecaConnection().getUserData().setGameUUIDs(new ArrayList<UUID>());
        } else if (String.valueOf(e).contains("AvatarLink")) {
            try {
                MecaCoreConnector.getMecaConnection().getUserData().setUserAvatar(getImage(String.valueOf(e).replace("AvatarLink ", "")));
            } catch (IOException e1) {
                Logger.logError(e1);
            }
        } else if (String.valueOf(e).contains("Rank")) {
            MecaCoreConnector.getMecaConnection().getUserData().setUserRank(String.valueOf(e).replace("Rank ", ""));
            MecaCoreConnector.getMecaConnection().getUserData().setUsername(LoginClient.getLoginClient().username.getText());
            LoginClient.getLoginClient().initDisplay();
        } else {
            Logger.logInfo(e);
        }
        if (String.valueOf(e).contains("fileCreate")) {
            createFile();
        }

        /*
         * Advertisments
         */
        if (String.valueOf(e).contains("advertSize")) {
            try {
                sortAdvertisments(Integer.parseInt(String.valueOf(e).replace("advertSize ", "")));
            } catch (NumberFormatException | MalformedURLException e1) {
                Logger.logError(e1);
            }
        }
        if (String.valueOf(e).contains("adImageURLs")) {
            imageURLs = String.valueOf(e).replace("adImageURLs ", "");
        }
        if (String.valueOf(e).contains("adImageLinks")) {
            imageLinks = String.valueOf(e).replace("adImageLinks ", "");
        }
        if (String.valueOf(e).contains("adImageViewChances")) {
            viewChances = String.valueOf(e).replace("adImageViewChances ", "");
        }

        /*
         * Games
         */

        if (String.valueOf(e).contains("gameUUIDs")) {

        }
        if (String.valueOf(e).contains("gameNames")) {

        }
        if (String.valueOf(e).contains("gameImageURLs")) {

        }
        if (String.valueOf(e).contains("gameBackgroundImageURLs")) {

        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        Logger.logError(cause);
        ctx.close();
    }

    public void createFile() {

    }

    private Image getImage(String url) throws MalformedURLException, IOException {
        HttpURLConnection con = (HttpURLConnection)new URL(url).openConnection();
        con.addRequestProperty("User-Agent", "Mozilla/4.76"); 
        InputStream in = con.getInputStream();
        Image img = ImageIO.read(in);
        return img;
    }

    private UUID[] parseUUIDs(String uuids) {
        String consUUID = "";
        UUID[] uuid = new UUID[uuids.length() / 36];
        for (int y = 0; y < uuid.length; y += 36) {
            consUUID = uuids.substring(y, y + 36);
            uuid[y] = UUID.fromString(consUUID);
        }
        return uuid;
    }

    private void sortAdvertisments(int size) throws MalformedURLException {
        ads = new Advertisment[size];
        for (int m = 0; m < size; m++) {
            Advertisment a = new Advertisment();
            a.getAd().setImageURL(new URL(getParsedArray(imageURLs)[m]));
            a.getAd().setImageLink(new URL(getParsedArray(imageLinks)[m]));
            a.getAd().setViewChance(Double.parseDouble(getParsedArray(viewChances)[m]));
            ads[m] = a;
        }
    }

    private Command getCommand(String message) {
        message = message.substring(0, message.indexOf(" "));
        return Command.valueOf(message);
    }

    private LoginDataType getLoginDataType(String message) {
        return LoginDataType.valueOf(message);
    }

    private DataType getDataType(String message) {
        return DataType.valueOf(message);
    }

    private String[] getParsedArray(String input) {
        return input.split(" ");
    }

    public static Advertisment[] getAdvertisments() {
        return ads;
    }

    public static MecaCoreConnectorAdapter getConnectionAdapter() {
        return instance;
    }
}

ServerChannelHandler (Server): ServerChannelHandler(服务器):

import io.netty.bootstrap.ServerBootstrap;
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.NioServerSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.Delimiters;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import net.meca.server.lib.Reference;

public class ServerChannelHandler  {

    /**
     * Initialize the Server Channel Handler
     * @throws InterruptedException 
     */

    public static void init() throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();

            b.group(bossGroup, workerGroup);

            b.channel(NioServerSocketChannel.class);

            b.childHandler(new ChannelInitializer<SocketChannel>() {
                 @Override
                 public void initChannel(SocketChannel ch) throws Exception {
                     ch.pipeline().addLast("framer", new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter()));
                     ch.pipeline().addLast("decoder", new StringDecoder());
                     ch.pipeline().addLast("encoder", new StringEncoder());
                     ch.pipeline().addLast("handler", new ServerChannelHandlerAdapter());
                 }
             });

             b.option(ChannelOption.SO_BACKLOG, 128);
             b.childOption(ChannelOption.SO_KEEPALIVE, true);

            ChannelFuture f = b.bind(Reference.port).sync();
            f.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
        }
    }
}

ServerChannelHandlerAdapter (Server): ServerChannelHandlerAdapter(服务器):

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.UUID;

import net.meca.server.lib.BufferedUtils;
import net.meca.server.lib.Reference;
import net.meca.server.logger.Logger;

public class ServerChannelHandlerAdapter extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        Logger.logInfo("Connected: " + ctx.channel());
        ctx.channel().write("Connected to MecaCore V" + Reference.version + "\n\r");
        ctx.channel().flush();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object e) throws Exception {
        Logger.logInfo(e);
        /*
         * Responses
         */
        if (String.valueOf(e).contains("Username:") && String.valueOf(e).contains("Password:")) {
            Logger.logInfo("Searching for UserData for " + e);
            int splitPoint = processString(String.valueOf(e).replace("Username:", "").replace("Password:", ""));
            String parsedUser = String.valueOf(e).replace("Username:", "").replace("Password:", "").substring(0, splitPoint);

            String parsedPass = String.valueOf(e).replace("Username:", "").replace("Password:", "").substring(splitPoint, String.valueOf(e).replace("Username:", "").replace("Password:", "").replace(" ", "").length() + 1).replace(" ", "");
            if (new File(MecaCore.getInstance().getProgramPath() + "UserData" + File.separator + parsedUser + File.separator + parsedPass).exists()) {
                ctx.channel().writeAndFlush("Login Details Valid, Logging in...");
                username = parsedUser;
                password = parsedPass;
            }
        } else {
            ctx.channel().write("[MecaCore] Login is Invalid!\n\r");
            return;
        }

        if (username != null && password != null) {
            try {
                fetchUserData(username, password);
                ctx.channel().write("\r\n" + "createUser" + "\r\n");
                ctx.channel().write("NumericID " + String.valueOf(numericID) + "\r\n");
                ctx.channel().write("UUID " + String.valueOf(uuid) + "\r\n");
                ctx.channel().write("GameUUIDs " + String.valueOf(gameUUIDs) + "\r\n");
                ctx.channel().write("AvatarLink " + String.valueOf(avatarLink) + "\r\n");
                ctx.channel().write("Rank " + String.valueOf(rank) + "\r\n");
            } catch (IOException e1) {
                Logger.logError(e1);
            }
        } else {
            Logger.logInfo("No Permission to access Server! Disconnecting...");
            ctx.write("No Permission to access Server! Disconnecting...");
            ctx.channel().disconnect();
            return;
        }
        ctx.channel().flush();
    }

    private String username;
    private String password;

    private String numericID;
    private UUID uuid;
    private String gameUUIDs;
    private String avatarLink;
    private String rank;

    private int processString(String replace) {
        return replace.indexOf(" ");
    }

    private void fetchUserData(String username, String password) throws UnsupportedEncodingException, IOException {
        String[] info = BufferedUtils.readFile(MecaCore.getInstance().getProgramPath() + "UserData" + File.separator + username + File.separator + password, 5);
        numericID = info[0];
        uuid = UUID.fromString(info[1]);
        gameUUIDs = info[2];
        avatarLink = info[3];
        rank = info[4];
    }
}

I also get this error when the client is forcefully disconnected from the server by shutting down the application forcefully 当通过强制关闭应用程序来强制断开客户端与服务器的连接时,也会出现此错误

    Sep 22, 2014 9:07:37 PM io.netty.channel.DefaultChannelPipeline$TailContext exceptionCaught
WARNING: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.io.IOException: Connection reset by peer
        at sun.nio.ch.FileDispatcherImpl.read0(Native Method)
        at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
        at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
        at sun.nio.ch.IOUtil.read(IOUtil.java:192)
        at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:375)
        at io.netty.buffer.UnpooledUnsafeDirectByteBuf.setBytes(UnpooledUnsafeDirectByteBuf.java:446)
        at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:881)
        at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:225)
        at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:119)
        at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
        at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
        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.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
        at java.lang.Thread.run(Thread.java:745)

I simply do not know how to make it stop freezing the client/server and i need help with this problem 我只是不知道如何使它停止冻结客户端/服务器,因此我需要有关此问题的帮助

You need to call flush() at some point to flush the data on the channel, otherwise it will just sit in the outbound queue. 您需要在某个时刻调用flush()刷新通道上的数据,否则它将仅位于出站队列中。 So for a "quick" fix replace write(...) with writeAndFlush(...). 因此,对于“快速”修复程序,将write(...)替换为writeAndFlush(...)。 You may want to think about a smarter way to not flush too often thought. 您可能需要考虑一种更聪明的方法,以免冲洗过于频繁。

I recommend you use Hercules to test your application separately, Hercules provides functions of client and server separately. 我建议您使用Hercules分别测试您的应用程序,Hercules分别提供客户端和服务器功能。 Then you can discard who is the problem, the client or the server. 然后,您可以丢弃问题的源头,客户端还是服务器。

Hope this help. 希望能有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM