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

时间:2014-09-22 19:13:39

标签: java netty

嗯我和Netty 3工作正常,但我想与Netty 4合作,我转换了代码并得到了以下所有内容,我不确定它是否是代码中的服务器问题和客户端问题,因为它并没有告诉我,甚至不是错误的来源,我也尝试不向服务器发送任何数据,它仍然做到了,我无法与客户端进行交互但是从测试它使应用程序占用更多内存非常缓慢而且我只发送字符串甚至不是40个字符

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(客户端):

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(服务器):

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(服务器):

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];
    }
}

当强制关闭应用程序强行断开客户端与服务器的连接时,我也会收到此错误

    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)

我根本不知道如何让它停止冻结客户端/服务器,我需要帮助解决这个问题

2 个答案:

答案 0 :(得分:0)

您需要在某个时刻调用flush()来刷新通道上的数据,否则它将只位于出站队列中。所以对于一个&#34;快速&#34;修复用writeAndFlush(...)替换write(...)。你可能想要考虑一种更聪明的方法,不要经常思考。

答案 1 :(得分:0)

我建议您使用Hercules单独测试您的应用程序,Hercules分别提供客户端和服务器的功能。然后您可以丢弃问题所在,客户端或服务器。

希望得到这个帮助。