Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/360.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服务器停止响应_Java_Netty - Fatal编程技术网

Java Netty服务器停止响应

Java Netty服务器停止响应,java,netty,Java,Netty,我有ServerHandshakeHandler,它扩展了ChannelInboundHandlerAdapter。客户端模拟对服务器的多重访问。通信成功一段时间后,当客户端尝试连接时,服务器停止响应。它不显示任何传入连接。客户端重启没有帮助,只是重启服务器 我试图在服务器停止响应时设置telnet连接:连接建立,但我无法从服务器获得任何响应(当服务器处于正常状态时,它会发送响应)。与nmap-v--packet trace-sT localhost-p{port}类似的情况:nmap发现端口是

我有
ServerHandshakeHandler
,它扩展了
ChannelInboundHandlerAdapter
。客户端模拟对服务器的多重访问。通信成功一段时间后,当客户端尝试连接时,服务器停止响应。它不显示任何传入连接。客户端重启没有帮助,只是重启服务器

我试图在服务器停止响应时设置telnet连接:连接建立,但我无法从服务器获得任何响应(当服务器处于正常状态时,它会发送响应)。与
nmap-v--packet trace-sT localhost-p{port}
类似的情况:nmap发现端口是打开的,但服务器上没有关于传入连接的日志信息

服务器:

public class ServerHandshakeHandler extends ChannelInboundHandlerAdapter {

private final ChannelGroup group;
private static final byte HANDSHAKE_SUCCEDED = 1;
private static final byte HANDSHAKE_FAILED = 0;
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());


public ServerHandshakeHandler(ChannelGroup group) {
    this.group = group;
}

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    LOG.debug("in ServerHandshakeHandler.channelRead");
    ByteBuf buf = (ByteBuf) msg;
    String someField = getSomeField(buf);
    ReferenceCountUtil.release(msg);

    if (someField.isEmpty()) {
        this.fireHandshakeFailed(ctx);
        return;
    }

    LOG.debug("Removing handshake handler from pipeline.");

    ctx.pipeline().remove(this);
    this.fireHandshakeSucceeded(ctx);

}

@Override
public void channelActive(final ChannelHandlerContext ctx) {
    LOG.debug("in ServerHandshakeHandler.channelActive, group size = " + this.group.size());
    this.group.add(ctx.channel());
    LOG.debug("Incoming connection from: {}",
            ctx.channel().remoteAddress().toString());
}

@Override
 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    LOG.error("exception caught ", cause);
    if (ctx.channel().isActive()) {
        ctx.channel().close();
    } else {
        this.fireHandshakeFailed(ctx);
    }
}

private void fireHandshakeFailed(ChannelHandlerContext ctx) {
    LOG.debug("fire handshake failed");
    ByteBuf buf = Unpooled.buffer(1);
    buf.writeByte(HANDSHAKE_FAILED);
    ctx.channel().writeAndFlush(buf);

    ctx.channel().close();
    ctx.fireUserEventTriggered(HandshakeEvent.handshakeFailed(ctx.channel()));
}

private void fireHandshakeSucceeded(ChannelHandlerContext ctx) {
    LOG.debug("fire handshake succeded");
    ByteBuf buf = Unpooled.buffer(1);
    buf.writeByte(HANDSHAKE_SUCCEDED);
    ctx.channel().writeAndFlush(buf);

    ctx.fireUserEventTriggered(HandshakeEvent
            .handshakeSucceeded(ctx.channel()));
}
}

客户:

public class MyClient {
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private String host;
private int port;
private Socket socket;

public Client(String host, int port) {
    this.host = host;
    this.port = port;
}

public void send(String id, String message) {
    try {
        socket = new Socket(host, port);
        LOG.debug("connected to server");

        if (performHandshake(id)) {
            LOG.debug("handshake success");
            sendMessage(message);
        }
        socket.close();;
    } catch (IOException ex) {
        LOG.error("error while sending data", ex);
    }
}

private boolean performHandshake(String id) {
    try {
        byte[] request = handshakeRequest(id);
        writeBytes(request);
        byte[] response = readBytes(1);
        return (response != null && response.length == 1 && response[0] == 1);
    } catch (IOException ex) {
        LOG.error("perform handshake error", ex);
        return false;
    }
}

private byte[] handshakeRequest(String id) throws UnsupportedEncodingException {...}

private void writeBytes(byte[] data) throws IOException {
    OutputStream out = socket.getOutputStream();
    out.write(data);
}

private byte[] readBytes(int length) throws IOException {
    InputStream in = socket.getInputStream();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte buffer[] = new byte[1024];
    int currentLength = 0;
    while (currentLength < length) {
        int size = in.read(buffer); //here client stops waiting server response
        if (size == -1) {
            throw new IOException("unexpected end of stream");
        }
        baos.write(buffer, 0, size);
        currentLength += size;
    }
    return baos.toByteArray();
}
公共类MyClient{
私有静态最终记录器LOG=LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
私有字符串主机;
专用int端口;
专用插座;
公共客户端(字符串主机,int端口){
this.host=host;
this.port=端口;
}
公共无效发送(字符串id、字符串消息){
试一试{
套接字=新套接字(主机、端口);
调试(“连接到服务器”);
if(执行握手(id)){
LOG.debug(“握手成功”);
发送消息(message);
}
socket.close();;
}捕获(IOEX异常){
LOG.error(“发送数据时出错”,例如);
}
}
私有布尔performHandshake(字符串id){
试一试{
字节[]请求=握手请求(id);
写字节(请求);
字节[]响应=读取字节(1);
返回(response!=null&&response.length==1&&response[0]==1);
}捕获(IOEX异常){
日志错误(“执行握手错误”,ex);
返回false;
}
}
私有字节[]握手请求(字符串id)引发不支持的编码异常{…}
私有void writeBytes(字节[]数据)引发IOException{
OutputStream out=socket.getOutputStream();
输出。写入(数据);
}
私有字节[]readBytes(int-length)引发IOException{
InputStream in=socket.getInputStream();
ByteArrayOutputStream bas=新的ByteArrayOutputStream();
字节缓冲区[]=新字节[1024];
int currentLength=0;
while(当前长度<长度){
int size=in.read(buffer);//此时客户端停止等待服务器响应
如果(大小==-1){
抛出新IOException(“意外的流结束”);
}
写入(缓冲区,0,大小);
当前长度+=大小;
}
返回baos.toByteArray();
}

}解决了!在我调用连接到数据库的同步函数时,有一段很窄的代码。由于某些原因,无法建立此连接,函数挂起。此函数中的线程进入状态。一段时间后,其他踏板尝试访问此功能并被阻止。这就是服务器停止处理传入连接的原因


我推荐jvisualvm评测工具,它帮助我找到了这个bug。

Hi,你能提供关于这个问题的更多信息吗。我也面临着类似的问题。然而,jvisualvm没有显示任何正在等待的相关线程。你能详细解释一下为什么等待数据库连接的函数会导致传入连接没有响应吗?@BandiKishore所有netty线程都试图调用一个挂起的同步方法,所有线程都在等待它进入。如果jvisualvm没有显示等待线程,那么可能您的问题与我的不同,嗯,我想是这样。谢谢你提供的信息:)@BandiKishore如果你能解决你的问题,我想如果你能在这里为其他人发布你的解决方案会很有用:)