Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Netty:在ctx.flush()之后保持服务器套接字打开_Java_Netty - Fatal编程技术网

Java Netty:在ctx.flush()之后保持服务器套接字打开

Java Netty:在ctx.flush()之后保持服务器套接字打开,java,netty,Java,Netty,我有两个服务器“A”(由我的朋友构建)和“B”(由我使用Netty 4.1构建)。当客户端发送命令时,服务器“A”和“B”将返回一些响应。我尝试使用简单的JAVA客户机套接字访问该服务器。以下是java客户端代码: public class SocketClient { public void run() { try { ClassLoader classLoader = getClass().getClassLoader();

我有两个服务器“A”(由我的朋友构建)和“B”(由我使用Netty 4.1构建)。当客户端发送命令时,服务器“A”和“B”将返回一些响应。我尝试使用简单的JAVA客户机套接字访问该服务器。以下是java客户端代码:

public class SocketClient
{
    public void run()
    {
        try {
            ClassLoader classLoader = getClass().getClassLoader();
            File file = new File(classLoader.getResource("request.txt").getFile());
            String content = new String(Files.readAllBytes(file.toPath()));

            System.out.println("Connecting to server:8888");
            Socket socket = new Socket("myserver.com", 8888);
            DataOutputStream out = new DataOutputStream(socket.getOutputStream());
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            out.write(content.getBytes());
            out.flush();

            while(true) {
                int response = in.read();
                System.out.println(response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
将客户机连接到服务器A(非netty)时,
read()
方法会给出如下输出:

48
48
57
56
48
50
49
48
48
48
57
56
48
50
49
48
-1
-1
-1
-1
但是,当我尝试连接到服务器“B”(使用netty)时,输出如下:

48
48
57
56
48
50
49
48
48
48
57
56
48
50
49
48
-1
-1
-1
-1
为什么会发生这种情况?顺便说一下,在服务器B中,我正在使用
ctx.write()和ctx.flush()
,以及如何使服务器B与服务器A具有相同的行为(不关闭连接,因此它不会返回-1)

编辑:附加信息

实际上,在服务器“B”中,我使用的是
ChannelInboundHandlerAdapter
ChannelOutboundHandlerAdapter
。进行一些实验后,问题出现在
ChannelOutboundHandlerAdapter
上。当我从
InboundAdapter
使用
ctx.writeAndFlush()发送响应时,套接字未关闭。但是当响应被传递到
OutboundAdapter
中,然后我使用
ctx.writeAndFlush()
inside
OutboundAdapter
write(ChannelHandlerContext ctx,Object msg,ChannelPromise promise)
方法发送响应时。插座是关着的

下面是我的
OutboundAdapter
的示例:

public class OutboundHandler extends ChannelOutboundHandlerAdapter {

    private static final Logger logger = LogManager.getLogger(OutboundHandler.class);

    //Sending or forwarding message to channel which is already configured
    //condition is depends on which model instance
    //packaging is worked on its packager class
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception
    {
        String response = "Response form OutboundHandler";
        ctx.writeAndFlush(Unpooled.copiedBuffer(response.getBytes()));
    } }

感谢Netty服务器实现上的

,例如,您可能必须更正确地通过ChannelHandlerContext处理读/写操作,而不是使用
ctx.write()
ctx.channel().writeandflush()
应该是更正确的方式,同样在关闭
ctx.channel().close()或
ctx.channel().close().sync()时也是如此()
可能会产生差异…

在Netty服务器实现上,可能您必须更正确地处理通过ChannelHandlerContext进行的读/写操作,例如,而不是使用
ctx.write()
ctx.channel().writeandflush()
应该是更正确的方式,也可以使用
ctx.channel().close()
ctx.channel().close().sync()
可能会产生差异…

您没有检查流的结尾,所以您正在无休止地回显它。
read()
返回一个值。检查它。它在流结束时返回-1。这就是结束。Finis.Finito。停在那里。不要打印它。不要继续阅读。不要通过GO。不要收取200美元。

你没有检查流结束,所以你在无休止地回显它。
read()
返回一个值。检查它。它在流的末尾返回-1。这就是结尾。Finis.Finito。停在那里。不要打印它。不要继续阅读。不要通过GO。不要收取200美元。

在调试了一整天之后,我发现了问题的根本原因。我不小心放了
ctx.close()
在我的InboundAdapter中的某个地方,因此当我将消息传递到OutboundAdapter并将消息刷新到客户端时,它将关闭连接

try {
   //some code
}
} catch (Exception ex) {
        logger.error(ex);
        ErrorData error = new ErrorData();
        error.setCode("99");
        error.setMessage("General System Error");

        //pass the message to OutboundAdapter
        ctx.writeAndFlush(error);
} finally {
  ctx.close();
}

因此,我只需要删除
ctx.close()
,服务器停止关闭套接字连接

调试一整天后,我发现了问题的根本原因。我不小心放入了
ctx.close()
在我的InboundAdapter中的某个地方,因此当我将消息传递到OutboundAdapter并将消息刷新到客户端时,它将关闭连接

try {
   //some code
}
} catch (Exception ex) {
        logger.error(ex);
        ErrorData error = new ErrorData();
        error.setCode("99");
        error.setMessage("General System Error");

        //pass the message to OutboundAdapter
        ctx.writeAndFlush(error);
} finally {
  ctx.close();
}

因此,我只需要删除
ctx.close()
,服务器停止关闭套接字连接

那么
ctx.writeAndFlush()
ctx.channel.writeAndFlush()
之间的区别是什么?我的问题是netty总是在
writeAndFlush()之后自动关闭连接
因此客户端无法向服务器发送另一条消息。它们在两种方式上都应该是相同的,它们实现了相同的ChannelOutboundInvoker接口,但对于您的问题,我提供了一些netty示例,可能对我使用netty.io(版本4.x)而不是jboss netty(版本3.x)的方式很有用,我不知道它们是否有显著差异。但感谢您的建议…哦,我已经尝试将
ctx.write();ctx.flush()
更改为
ctx.channel().writeAndFlush())
但是套接字仍然会自动关闭。没有writeAndFlush并不能解决您的问题,您的第一个注释代码的逻辑是正确的,对于您的情况,它应该是先写然后刷新…ctx.writeAndFlush()和
ctx.channel.writeAndFlush()之间的区别是什么
?我的问题是,netty总是在
writeAndFlush()之后自动关闭连接,因此客户端无法向服务器发送另一条消息。它们在两种方式上应该是相同的,它们实现了相同的ChannelOutboundInvoker接口。不过,对于您的问题,我提供了一些netty示例,通过我使用netty.io的方式可能会很有用(4.x版)而不是jboss netty(3.x版),我不知道它们是否有显著差异。但是感谢您的建议…哦,我已经尝试将
ctx.write();ctx.flush()
更改为
ctx.channel().writeAndFlush())
但是套接字仍然会自动关闭。没有writeAndFlush并不能解决您的问题,您的第一个注释代码的逻辑是正确的,它应该像写然后刷新一样适合您的情况。。。
try {
   //some code
}
} catch (Exception ex) {
        logger.error(ex);
        ErrorData error = new ErrorData();
        error.setCode("99");
        error.setMessage("General System Error");

        //pass the message to OutboundAdapter
        ctx.writeAndFlush(error);
} finally {
  ctx.close();
}