我正在尝试设置套接字的SO_KEEPALIVE时间。

我创建了一个类SocketBuilder以使用SocketImpl构建套接字实例。源代码如下,

public class SocketBuilder {

    private static SocketImpl si;

    public static Socket createCVPSocket() throws Exception {
        if (si == null) {
            init();
        }
        return new CSocket(si);
    }


    private static void init() throws SocketException {
        @SuppressWarnings("rawtypes")
        Constructor cons = null;
        try {
            cons = Class.forName("java.net.SocksSocketImpl")
                    .getDeclaredConstructor();
        } catch (NoSuchMethodException | SecurityException
                | ClassNotFoundException e) {
            throw new RuntimeException(
                    "Not able to access socket implementation.");
        }
        cons.setAccessible(true);
        SocketImpl si = null;
        try {
            si = (SocketImpl) cons.newInstance();
        } catch (InstantiationException | IllegalAccessException
                | IllegalArgumentException | InvocationTargetException e) {
            throw new RuntimeException("Not able to create instance of socket.");
        }
        if (si != null) {
            si.setOption(SocketImpl.SO_KEEPALIVE, new Integer(60));
        }
    }

    private static class CSocket extends Socket {
        protected CSocket(SocketImpl si) throws SocketException, Exception {
            super(si);
        }
    }
    public static void main(String[] args) {
        try {
            Socket sock = SocketBuilder.createCVPSocket();
            System.out.println(sock);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


我收到java.net.SocketException: Socket Closed异常。如果我删除si.setOption(SocketImpl.SO_KEEPALIVE, new Integer(60));行,则可以正常工作。但是我要设置SocketImpl.SO_KEEPALIVE。如何设置套接字的SO_KEEPALIVE

最佳答案

您的代码中有一些错误:


SocketImpl si = null;此声明与您的课程领域重叠
setOption仅在打开/连接套接字时有效
完成后必须关闭插座

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.*;

public class SocketBuilder {
private static SocketImpl si;

public static Socket createCVPSocket() throws Exception {
    if (si == null) {
        init();
    }
    return new CSocket(si);
}


private static void init() throws SocketException {
    @SuppressWarnings("rawtypes")
    Constructor cons = null;
    try {
        cons = Class.forName("java.net.SocksSocketImpl")
                .getDeclaredConstructor();
    } catch (NoSuchMethodException | SecurityException
            | ClassNotFoundException e) {
        throw new RuntimeException(
                "Not able to access socket implementation.");
    }
    cons.setAccessible(true);
    si = null;
    try {
        si = (SocketImpl) cons.newInstance();
    } catch (InstantiationException | IllegalAccessException
            | IllegalArgumentException | InvocationTargetException e) {
        throw new RuntimeException("Not able to create instance of socket.");
    }

}

private static class CSocket extends Socket {
    protected CSocket(SocketImpl si) throws SocketException, Exception {
        super(si);
        super.bind(new InetSocketAddress("127.0.0.1", 8888));

        si.setOption(SocketImpl.SO_KEEPALIVE, Boolean.TRUE);
    }
}
public static void main(String[] args) {
    try {
        Socket sock = SocketBuilder.createCVPSocket();
        System.out.println(sock);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


}

09-11 19:36