Java Netty 4.0客户端/服务器在连接时冻结
我在Netty 3上工作正常,但我想在Netty 4上工作,我转换了代码,得到了下面的所有信息,我不确定代码中是否存在服务器问题和客户端问题,因为它没有告诉我,甚至没有告诉我错误的来源,我也尝试过不向服务器发送数据,但它仍然这样做,我不能与客户机交互,但从测试来看,它会使应用程序占用更多的ram,速度非常慢,我只发送长度甚至不超过40个字符的字符串 MecaCoreConnector(客户): 当客户端通过强制关闭应用程序而强制断开与服务器的连接时,我也会遇到此错误Java Netty 4.0客户端/服务器在连接时冻结,java,netty,Java,Netty,我在Netty 3上工作正常,但我想在Netty 4上工作,我转换了代码,得到了下面的所有信息,我不确定代码中是否存在服务器问题和客户端问题,因为它没有告诉我,甚至没有告诉我错误的来源,我也尝试过不向服务器发送数据,但它仍然这样做,我不能与客户机交互,但从测试来看,它会使应用程序占用更多的ram,速度非常慢,我只发送长度甚至不超过40个字符的字符串 MecaCoreConnector(客户): 当客户端通过强制关闭应用程序而强制断开与服务器的连接时,我也会遇到此错误 Sep 22, 20
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)
我只是不知道如何让它停止冻结客户端/服务器,我需要有关此问题的帮助您需要在某个时候调用flush(),以刷新通道上的数据,否则它将只位于出站队列中。因此,对于“快速”修复,请将write(…)替换为writeAndFlush(…)。您可能需要考虑一种更聪明的方法,以避免频繁刷新。我建议您单独测试应用程序,Hercules分别提供客户端和服务器功能。然后,您可以放弃谁是问题所在,客户机还是服务器
希望获得此帮助。寻求调试帮助的问题(“为什么此代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现这些问题所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅。编辑器删除了问题的底部部分:/啊,我做了一个编辑,应该将堆栈跟踪与最后一个代码块分开显示;)我尝试了多种刷新数据的方法,但似乎仍然如此,所以我不确定是否是这样,但感谢您建议我删除数据Java 8 Update 11和Netty 4.0是否存在已知问题?我已经更新了代码,因此有很多新的方法可以帮助您回答我的问题:)@TheCheatgamer1-我也面临当客户端和服务器之间存在强制断开连接时,也会出现同样的问题。你能解决这个问题吗?Iv已经制作了一个api来记录从我的应用程序传入和传出的每个字节,但谢谢:)
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;
}
}
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();
}
}
}
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)